KCL: Add planeOf function to stdlib (#7643)
Gets the plane a face lies on, if any. Closes #7642
This commit is contained in:
		
							
								
								
									
										48
									
								
								docs/kcl-std/functions/std-sketch-planeOf.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								docs/kcl-std/functions/std-sketch-planeOf.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -67,6 +67,7 @@ layout: manual
 | 
			
		||||
  * [`patternCircular2d`](/docs/kcl-std/functions/std-sketch-patternCircular2d)
 | 
			
		||||
  * [`patternLinear2d`](/docs/kcl-std/functions/std-sketch-patternLinear2d)
 | 
			
		||||
  * [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
 | 
			
		||||
  * [`planeOf`](/docs/kcl-std/functions/std-sketch-planeOf)
 | 
			
		||||
  * [`polygon`](/docs/kcl-std/functions/std-sketch-polygon)
 | 
			
		||||
  * [`profileStart`](/docs/kcl-std/functions/std-sketch-profileStart)
 | 
			
		||||
  * [`profileStartX`](/docs/kcl-std/functions/std-sketch-profileStartX)
 | 
			
		||||
 | 
			
		||||
@ -32,6 +32,7 @@ This module contains functions for creating and manipulating sketches, and makin
 | 
			
		||||
* [`patternCircular2d`](/docs/kcl-std/functions/std-sketch-patternCircular2d)
 | 
			
		||||
* [`patternLinear2d`](/docs/kcl-std/functions/std-sketch-patternLinear2d)
 | 
			
		||||
* [`patternTransform2d`](/docs/kcl-std/functions/std-sketch-patternTransform2d)
 | 
			
		||||
* [`planeOf`](/docs/kcl-std/functions/std-sketch-planeOf)
 | 
			
		||||
* [`polygon`](/docs/kcl-std/functions/std-sketch-polygon)
 | 
			
		||||
* [`profileStart`](/docs/kcl-std/functions/std-sketch-profileStart)
 | 
			
		||||
* [`profileStartX`](/docs/kcl-std/functions/std-sketch-profileStartX)
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,9 @@ lint:
 | 
			
		||||
    # Ensure we can build without extra feature flags.
 | 
			
		||||
    cargo clippy -p kcl-lib --all-targets -- -D warnings
 | 
			
		||||
 | 
			
		||||
lint-fix:
 | 
			
		||||
    cargo clippy --workspace --all-targets --all-features --fix
 | 
			
		||||
 | 
			
		||||
# Run the stdlib docs generation
 | 
			
		||||
redo-kcl-stdlib-docs-no-imgs:
 | 
			
		||||
    EXPECTORATE=overwrite {{cnr}} {{kcl_lib_flags}} docs::gen_std_tests::test_generate_stdlib
 | 
			
		||||
 | 
			
		||||
@ -97,6 +97,7 @@ pub const TEST_NAMES: &[&str] = &[
 | 
			
		||||
    "std-offsetPlane-2",
 | 
			
		||||
    "std-offsetPlane-3",
 | 
			
		||||
    "std-offsetPlane-4",
 | 
			
		||||
    "std-sketch-planeOf-0",
 | 
			
		||||
    "std-sketch-circle-0",
 | 
			
		||||
    "std-sketch-circle-1",
 | 
			
		||||
    "std-sketch-patternTransform2d-0",
 | 
			
		||||
 | 
			
		||||
@ -226,10 +226,7 @@ impl From<&KclValue> for OpKclValue {
 | 
			
		||||
        match value {
 | 
			
		||||
            KclValue::Uuid { value, .. } => Self::Uuid { value: *value },
 | 
			
		||||
            KclValue::Bool { value, .. } => Self::Bool { value: *value },
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Self::Number {
 | 
			
		||||
                value: *value,
 | 
			
		||||
                ty: ty.clone(),
 | 
			
		||||
            },
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Self::Number { value: *value, ty: *ty },
 | 
			
		||||
            KclValue::String { value, .. } => Self::String { value: value.clone() },
 | 
			
		||||
            KclValue::Tuple { value, .. } | KclValue::HomArray { value, .. } => {
 | 
			
		||||
                let value = value.iter().map(Self::from).collect();
 | 
			
		||||
 | 
			
		||||
@ -1297,7 +1297,7 @@ impl Node<UnaryExpression> {
 | 
			
		||||
                Ok(KclValue::Number {
 | 
			
		||||
                    value: -value,
 | 
			
		||||
                    meta,
 | 
			
		||||
                    ty: ty.clone(),
 | 
			
		||||
                    ty: *ty,
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
            KclValue::Plane { value } => {
 | 
			
		||||
@ -1329,7 +1329,7 @@ impl Node<UnaryExpression> {
 | 
			
		||||
                            .map(|v| match v {
 | 
			
		||||
                                KclValue::Number { value, ty, meta } => Ok(KclValue::Number {
 | 
			
		||||
                                    value: *value * -1.0,
 | 
			
		||||
                                    ty: ty.clone(),
 | 
			
		||||
                                    ty: *ty,
 | 
			
		||||
                                    meta: meta.clone(),
 | 
			
		||||
                                }),
 | 
			
		||||
                                _ => Err(err()),
 | 
			
		||||
@ -1350,7 +1350,7 @@ impl Node<UnaryExpression> {
 | 
			
		||||
                            .map(|v| match v {
 | 
			
		||||
                                KclValue::Number { value, ty, meta } => Ok(KclValue::Number {
 | 
			
		||||
                                    value: *value * -1.0,
 | 
			
		||||
                                    ty: ty.clone(),
 | 
			
		||||
                                    ty: *ty,
 | 
			
		||||
                                    meta: meta.clone(),
 | 
			
		||||
                                }),
 | 
			
		||||
                                _ => Err(err()),
 | 
			
		||||
@ -1544,7 +1544,7 @@ impl Node<ArrayRangeExpression> {
 | 
			
		||||
                .into_iter()
 | 
			
		||||
                .map(|num| KclValue::Number {
 | 
			
		||||
                    value: num as f64,
 | 
			
		||||
                    ty: start_ty.clone(),
 | 
			
		||||
                    ty: start_ty,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                })
 | 
			
		||||
                .collect(),
 | 
			
		||||
 | 
			
		||||
@ -939,6 +939,7 @@ impl From<Point3d> for Point3D {
 | 
			
		||||
        Self { x: p.x, y: p.y, z: p.z }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl From<Point3d> for kittycad_modeling_cmds::shared::Point3d<LengthUnit> {
 | 
			
		||||
    fn from(p: Point3d) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
@ -1004,12 +1005,12 @@ pub struct BasePath {
 | 
			
		||||
impl BasePath {
 | 
			
		||||
    pub fn get_to(&self) -> [TyF64; 2] {
 | 
			
		||||
        let ty: NumericType = self.units.into();
 | 
			
		||||
        [TyF64::new(self.to[0], ty.clone()), TyF64::new(self.to[1], ty)]
 | 
			
		||||
        [TyF64::new(self.to[0], ty), TyF64::new(self.to[1], ty)]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_from(&self) -> [TyF64; 2] {
 | 
			
		||||
        let ty: NumericType = self.units.into();
 | 
			
		||||
        [TyF64::new(self.from[0], ty.clone()), TyF64::new(self.from[1], ty)]
 | 
			
		||||
        [TyF64::new(self.from[0], ty), TyF64::new(self.from[1], ty)]
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1225,14 +1226,14 @@ impl Path {
 | 
			
		||||
    pub fn get_from(&self) -> [TyF64; 2] {
 | 
			
		||||
        let p = &self.get_base().from;
 | 
			
		||||
        let ty: NumericType = self.get_base().units.into();
 | 
			
		||||
        [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)]
 | 
			
		||||
        [TyF64::new(p[0], ty), TyF64::new(p[1], ty)]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Where does this path segment end?
 | 
			
		||||
    pub fn get_to(&self) -> [TyF64; 2] {
 | 
			
		||||
        let p = &self.get_base().to;
 | 
			
		||||
        let ty: NumericType = self.get_base().units.into();
 | 
			
		||||
        [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)]
 | 
			
		||||
        [TyF64::new(p[0], ty), TyF64::new(p[1], ty)]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The path segment start point and its type.
 | 
			
		||||
 | 
			
		||||
@ -415,15 +415,41 @@ impl KclValue {
 | 
			
		||||
 | 
			
		||||
    /// Put the point into a KCL value.
 | 
			
		||||
    pub fn from_point2d(p: [f64; 2], ty: NumericType, meta: Vec<Metadata>) -> Self {
 | 
			
		||||
        let [x, y] = p;
 | 
			
		||||
        Self::Tuple {
 | 
			
		||||
            value: vec![
 | 
			
		||||
                Self::Number {
 | 
			
		||||
                    value: p[0],
 | 
			
		||||
                    value: x,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                    ty: ty.clone(),
 | 
			
		||||
                    ty,
 | 
			
		||||
                },
 | 
			
		||||
                Self::Number {
 | 
			
		||||
                    value: p[1],
 | 
			
		||||
                    value: y,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                    ty,
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
            meta,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Put the point into a KCL value.
 | 
			
		||||
    pub fn from_point3d(p: [f64; 3], ty: NumericType, meta: Vec<Metadata>) -> Self {
 | 
			
		||||
        let [x, y, z] = p;
 | 
			
		||||
        Self::Tuple {
 | 
			
		||||
            value: vec![
 | 
			
		||||
                Self::Number {
 | 
			
		||||
                    value: x,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                    ty,
 | 
			
		||||
                },
 | 
			
		||||
                Self::Number {
 | 
			
		||||
                    value: y,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                    ty,
 | 
			
		||||
                },
 | 
			
		||||
                Self::Number {
 | 
			
		||||
                    value: z,
 | 
			
		||||
                    meta: meta.clone(),
 | 
			
		||||
                    ty,
 | 
			
		||||
                },
 | 
			
		||||
@ -448,7 +474,7 @@ impl KclValue {
 | 
			
		||||
 | 
			
		||||
    pub fn as_int_with_ty(&self) -> Option<(i64, NumericType)> {
 | 
			
		||||
        match self {
 | 
			
		||||
            KclValue::Number { value, ty, .. } => crate::try_f64_to_i64(*value).map(|i| (i, ty.clone())),
 | 
			
		||||
            KclValue::Number { value, ty, .. } => crate::try_f64_to_i64(*value).map(|i| (i, *ty)),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -562,7 +588,7 @@ impl KclValue {
 | 
			
		||||
 | 
			
		||||
    pub fn as_ty_f64(&self) -> Option<TyF64> {
 | 
			
		||||
        match self {
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Some(TyF64::new(*value, ty.clone())),
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Some(TyF64::new(*value, *ty)),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -460,7 +460,7 @@ impl fmt::Display for PrimitiveType {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)]
 | 
			
		||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, ts_rs::TS, JsonSchema)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
#[serde(tag = "type")]
 | 
			
		||||
pub enum NumericType {
 | 
			
		||||
@ -575,7 +575,7 @@ impl NumericType {
 | 
			
		||||
            match (&ty, &i.ty) {
 | 
			
		||||
                (Any, Default { .. }) if i.n == 0.0 => {}
 | 
			
		||||
                (Any, t) => {
 | 
			
		||||
                    ty = t.clone();
 | 
			
		||||
                    ty = *t;
 | 
			
		||||
                }
 | 
			
		||||
                (_, Unknown) | (Default { .. }, Default { .. }) => return (result, Unknown),
 | 
			
		||||
 | 
			
		||||
@ -598,7 +598,7 @@ impl NumericType {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ty == Any && !input.is_empty() {
 | 
			
		||||
            ty = input[0].ty.clone();
 | 
			
		||||
            ty = input[0].ty;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        (result, ty)
 | 
			
		||||
@ -722,7 +722,7 @@ impl NumericType {
 | 
			
		||||
        if ty.subtype(self) {
 | 
			
		||||
            return Ok(KclValue::Number {
 | 
			
		||||
                value: *value,
 | 
			
		||||
                ty: ty.clone(),
 | 
			
		||||
                ty: *ty,
 | 
			
		||||
                meta: meta.clone(),
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
@ -736,7 +736,7 @@ impl NumericType {
 | 
			
		||||
 | 
			
		||||
            (Any, _) => Ok(KclValue::Number {
 | 
			
		||||
                value: *value,
 | 
			
		||||
                ty: self.clone(),
 | 
			
		||||
                ty: *self,
 | 
			
		||||
                meta: meta.clone(),
 | 
			
		||||
            }),
 | 
			
		||||
 | 
			
		||||
@ -744,7 +744,7 @@ impl NumericType {
 | 
			
		||||
            // means accept any number rather than force the current default.
 | 
			
		||||
            (_, Default { .. }) => Ok(KclValue::Number {
 | 
			
		||||
                value: *value,
 | 
			
		||||
                ty: ty.clone(),
 | 
			
		||||
                ty: *ty,
 | 
			
		||||
                meta: meta.clone(),
 | 
			
		||||
            }),
 | 
			
		||||
 | 
			
		||||
@ -1491,7 +1491,7 @@ impl KclValue {
 | 
			
		||||
    pub fn principal_type(&self) -> Option<RuntimeType> {
 | 
			
		||||
        match self {
 | 
			
		||||
            KclValue::Bool { .. } => Some(RuntimeType::Primitive(PrimitiveType::Boolean)),
 | 
			
		||||
            KclValue::Number { ty, .. } => Some(RuntimeType::Primitive(PrimitiveType::Number(ty.clone()))),
 | 
			
		||||
            KclValue::Number { ty, .. } => Some(RuntimeType::Primitive(PrimitiveType::Number(*ty))),
 | 
			
		||||
            KclValue::String { .. } => Some(RuntimeType::Primitive(PrimitiveType::String)),
 | 
			
		||||
            KclValue::Object { value, .. } => {
 | 
			
		||||
                let properties = value
 | 
			
		||||
 | 
			
		||||
@ -3632,3 +3632,24 @@ mod non_english_identifiers {
 | 
			
		||||
        super::execute(TEST_NAME, true).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
mod plane_of {
 | 
			
		||||
    const TEST_NAME: &str = "plane_of";
 | 
			
		||||
 | 
			
		||||
    /// Test parsing KCL.
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn parse() {
 | 
			
		||||
        super::parse(TEST_NAME)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Test that parsing and unparsing KCL produces the original KCL input.
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn unparse() {
 | 
			
		||||
        super::unparse(TEST_NAME).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Test that KCL is executed correctly.
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn kcl_test_execute() {
 | 
			
		||||
        super::execute(TEST_NAME, true).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -340,12 +340,12 @@ impl Args {
 | 
			
		||||
        let x = KclValue::Number {
 | 
			
		||||
            value: p[0],
 | 
			
		||||
            meta: vec![meta],
 | 
			
		||||
            ty: ty.clone(),
 | 
			
		||||
            ty,
 | 
			
		||||
        };
 | 
			
		||||
        let y = KclValue::Number {
 | 
			
		||||
            value: p[1],
 | 
			
		||||
            meta: vec![meta],
 | 
			
		||||
            ty: ty.clone(),
 | 
			
		||||
            ty,
 | 
			
		||||
        };
 | 
			
		||||
        let ty = RuntimeType::Primitive(PrimitiveType::Number(ty));
 | 
			
		||||
 | 
			
		||||
@ -1038,7 +1038,7 @@ impl<'a> FromKclValue<'a> for u64 {
 | 
			
		||||
impl<'a> FromKclValue<'a> for TyF64 {
 | 
			
		||||
    fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
 | 
			
		||||
        match arg {
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Some(TyF64::new(*value, ty.clone())),
 | 
			
		||||
            KclValue::Number { value, ty, .. } => Some(TyF64::new(*value, *ty)),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -256,6 +256,10 @@ pub(crate) fn std_fn(path: &str, fn_name: &str) -> (crate::std::StdFn, StdFnProp
 | 
			
		||||
            |e, a| Box::pin(crate::std::shapes::circle(e, a)),
 | 
			
		||||
            StdFnProps::default("std::sketch::circle"),
 | 
			
		||||
        ),
 | 
			
		||||
        ("sketch", "planeOf") => (
 | 
			
		||||
            |e, a| Box::pin(crate::std::planes::plane_of(e, a)),
 | 
			
		||||
            StdFnProps::default("std::sketch::planeOf"),
 | 
			
		||||
        ),
 | 
			
		||||
        ("sketch", "extrude") => (
 | 
			
		||||
            |e, a| Box::pin(crate::std::extrude::extrude(e, a)),
 | 
			
		||||
            StdFnProps::default("std::sketch::extrude").include_in_feature_tree(),
 | 
			
		||||
 | 
			
		||||
@ -408,7 +408,7 @@ impl GeometryTrait for Sketch {
 | 
			
		||||
        exec_state: &mut ExecState,
 | 
			
		||||
    ) -> Result<[TyF64; 3], KclError> {
 | 
			
		||||
        let [x, y] = array_to_point2d(val, source_ranges, exec_state)?;
 | 
			
		||||
        let ty = x.ty.clone();
 | 
			
		||||
        let ty = x.ty;
 | 
			
		||||
        Ok([x, y, TyF64::new(0.0, ty)])
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,123 @@
 | 
			
		||||
//! Standard library plane helpers.
 | 
			
		||||
 | 
			
		||||
use kcmc::{ModelingCmd, each_cmd as mcmd, length_unit::LengthUnit, shared::Color};
 | 
			
		||||
use kittycad_modeling_cmds as kcmc;
 | 
			
		||||
use kittycad_modeling_cmds::{self as kcmc, ok_response::OkModelingCmdResponse, websocket::OkWebSocketResponseData};
 | 
			
		||||
 | 
			
		||||
use super::{args::TyF64, sketch::PlaneData};
 | 
			
		||||
use super::{
 | 
			
		||||
    args::TyF64,
 | 
			
		||||
    sketch::{FaceTag, PlaneData},
 | 
			
		||||
};
 | 
			
		||||
use crate::{
 | 
			
		||||
    errors::KclError,
 | 
			
		||||
    execution::{ExecState, KclValue, ModelingCmdMeta, Plane, PlaneType, types::RuntimeType},
 | 
			
		||||
    UnitLen,
 | 
			
		||||
    errors::{KclError, KclErrorDetails},
 | 
			
		||||
    execution::{ExecState, KclValue, Metadata, ModelingCmdMeta, Plane, PlaneType, types::RuntimeType},
 | 
			
		||||
    std::Args,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Find the plane of a given face.
 | 
			
		||||
pub async fn plane_of(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    let solid = args.get_unlabeled_kw_arg("solid", &RuntimeType::solid(), exec_state)?;
 | 
			
		||||
    let face = args.get_kw_arg("face", &RuntimeType::tagged_face(), exec_state)?;
 | 
			
		||||
 | 
			
		||||
    inner_plane_of(solid, face, exec_state, &args)
 | 
			
		||||
        .await
 | 
			
		||||
        .map(Box::new)
 | 
			
		||||
        .map(|value| KclValue::Plane { value })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async fn inner_plane_of(
 | 
			
		||||
    solid: crate::execution::Solid,
 | 
			
		||||
    face: FaceTag,
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: &Args,
 | 
			
		||||
) -> Result<Plane, KclError> {
 | 
			
		||||
    // Support mock execution
 | 
			
		||||
    // Return an arbitrary (incorrect) plane and a non-fatal error.
 | 
			
		||||
    if args.ctx.no_engine_commands().await {
 | 
			
		||||
        let plane_id = exec_state.id_generator().next_uuid();
 | 
			
		||||
        exec_state.err(crate::CompilationError {
 | 
			
		||||
            source_range: args.source_range,
 | 
			
		||||
            message: "The engine isn't available, so returning an arbitrary incorrect plane".to_owned(),
 | 
			
		||||
            suggestion: None,
 | 
			
		||||
            severity: crate::errors::Severity::Error,
 | 
			
		||||
            tag: crate::errors::Tag::None,
 | 
			
		||||
        });
 | 
			
		||||
        return Ok(Plane {
 | 
			
		||||
            artifact_id: plane_id.into(),
 | 
			
		||||
            id: plane_id,
 | 
			
		||||
            // Engine doesn't know about the ID we created, so set this to Uninit.
 | 
			
		||||
            value: PlaneType::Uninit,
 | 
			
		||||
            info: crate::execution::PlaneInfo {
 | 
			
		||||
                origin: Default::default(),
 | 
			
		||||
                x_axis: Default::default(),
 | 
			
		||||
                y_axis: Default::default(),
 | 
			
		||||
            },
 | 
			
		||||
            meta: vec![Metadata {
 | 
			
		||||
                source_range: args.source_range,
 | 
			
		||||
            }],
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Query the engine to learn what plane, if any, this face is on.
 | 
			
		||||
    let face_id = face.get_face_id(&solid, exec_state, args, true).await?;
 | 
			
		||||
    let meta = args.into();
 | 
			
		||||
    let cmd = ModelingCmd::FaceIsPlanar(mcmd::FaceIsPlanar { object_id: face_id });
 | 
			
		||||
    let plane_resp = exec_state.send_modeling_cmd(meta, cmd).await?;
 | 
			
		||||
    let OkWebSocketResponseData::Modeling {
 | 
			
		||||
        modeling_response: OkModelingCmdResponse::FaceIsPlanar(planar),
 | 
			
		||||
    } = plane_resp
 | 
			
		||||
    else {
 | 
			
		||||
        return Err(KclError::new_semantic(KclErrorDetails::new(
 | 
			
		||||
            format!(
 | 
			
		||||
                "Engine returned invalid response, it should have returned FaceIsPlanar but it returned {plane_resp:#?}"
 | 
			
		||||
            ),
 | 
			
		||||
            vec![args.source_range],
 | 
			
		||||
        )));
 | 
			
		||||
    };
 | 
			
		||||
    // Destructure engine's response to check if the face was on a plane.
 | 
			
		||||
    let not_planar: Result<_, KclError> = Err(KclError::new_semantic(KclErrorDetails::new(
 | 
			
		||||
        "The face you provided doesn't lie on any plane. It might be curved.".to_owned(),
 | 
			
		||||
        vec![args.source_range],
 | 
			
		||||
    )));
 | 
			
		||||
    let Some(x_axis) = planar.x_axis else { return not_planar };
 | 
			
		||||
    let Some(y_axis) = planar.y_axis else { return not_planar };
 | 
			
		||||
    let Some(origin) = planar.origin else { return not_planar };
 | 
			
		||||
 | 
			
		||||
    // Engine always returns measurements in mm.
 | 
			
		||||
    let engine_units = UnitLen::Mm;
 | 
			
		||||
    let x_axis = crate::execution::Point3d {
 | 
			
		||||
        x: x_axis.x,
 | 
			
		||||
        y: x_axis.y,
 | 
			
		||||
        z: x_axis.z,
 | 
			
		||||
        units: engine_units,
 | 
			
		||||
    };
 | 
			
		||||
    let y_axis = crate::execution::Point3d {
 | 
			
		||||
        x: y_axis.x,
 | 
			
		||||
        y: y_axis.y,
 | 
			
		||||
        z: y_axis.z,
 | 
			
		||||
        units: engine_units,
 | 
			
		||||
    };
 | 
			
		||||
    let origin = crate::execution::Point3d {
 | 
			
		||||
        x: origin.x.0,
 | 
			
		||||
        y: origin.y.0,
 | 
			
		||||
        z: origin.z.0,
 | 
			
		||||
        units: engine_units,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Engine doesn't send back an ID, so let's just make a new plane ID.
 | 
			
		||||
    let plane_id = exec_state.id_generator().next_uuid();
 | 
			
		||||
    Ok(Plane {
 | 
			
		||||
        artifact_id: plane_id.into(),
 | 
			
		||||
        id: plane_id,
 | 
			
		||||
        // Engine doesn't know about the ID we created, so set this to Uninit.
 | 
			
		||||
        value: PlaneType::Uninit,
 | 
			
		||||
        info: crate::execution::PlaneInfo { origin, x_axis, y_axis },
 | 
			
		||||
        meta: vec![Metadata {
 | 
			
		||||
            source_range: args.source_range,
 | 
			
		||||
        }],
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Offset a plane by a distance along its normal.
 | 
			
		||||
pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
 | 
			
		||||
    let std_plane = args.get_unlabeled_kw_arg("plane", &RuntimeType::plane(), exec_state)?;
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ pub async fn segment_end(exec_state: &mut ExecState, args: Args) -> Result<KclVa
 | 
			
		||||
    let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tagged_edge(), exec_state)?;
 | 
			
		||||
    let pt = inner_segment_end(&tag, exec_state, args.clone())?;
 | 
			
		||||
 | 
			
		||||
    args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
 | 
			
		||||
    args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<[TyF64; 2], KclError> {
 | 
			
		||||
@ -31,7 +31,7 @@ fn inner_segment_end(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args
 | 
			
		||||
    })?;
 | 
			
		||||
    let (p, ty) = path.end_point_components();
 | 
			
		||||
    // Docs generation isn't smart enough to handle ([f64; 2], NumericType).
 | 
			
		||||
    let point = [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)];
 | 
			
		||||
    let point = [TyF64::new(p[0], ty), TyF64::new(p[1], ty)];
 | 
			
		||||
 | 
			
		||||
    Ok(point)
 | 
			
		||||
}
 | 
			
		||||
@ -81,7 +81,7 @@ pub async fn segment_start(exec_state: &mut ExecState, args: Args) -> Result<Kcl
 | 
			
		||||
    let tag: TagIdentifier = args.get_unlabeled_kw_arg("tag", &RuntimeType::tagged_edge(), exec_state)?;
 | 
			
		||||
    let pt = inner_segment_start(&tag, exec_state, args.clone())?;
 | 
			
		||||
 | 
			
		||||
    args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty.clone())
 | 
			
		||||
    args.make_kcl_val_from_point([pt[0].n, pt[1].n], pt[0].ty)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Args) -> Result<[TyF64; 2], KclError> {
 | 
			
		||||
@ -94,7 +94,7 @@ fn inner_segment_start(tag: &TagIdentifier, exec_state: &mut ExecState, args: Ar
 | 
			
		||||
    })?;
 | 
			
		||||
    let (p, ty) = path.start_point_components();
 | 
			
		||||
    // Docs generation isn't smart enough to handle ([f64; 2], NumericType).
 | 
			
		||||
    let point = [TyF64::new(p[0], ty.clone()), TyF64::new(p[1], ty)];
 | 
			
		||||
    let point = [TyF64::new(p[0], ty), TyF64::new(p[1], ty)];
 | 
			
		||||
 | 
			
		||||
    Ok(point)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,7 @@ async fn inner_circle(
 | 
			
		||||
 | 
			
		||||
    let radius = get_radius(radius, diameter, args.source_range)?;
 | 
			
		||||
    let from = [center_u[0] + radius.to_length_units(units), center_u[1]];
 | 
			
		||||
    let from_t = [TyF64::new(from[0], ty.clone()), TyF64::new(from[1], ty)];
 | 
			
		||||
    let from_t = [TyF64::new(from[0], ty), TyF64::new(from[1], ty)];
 | 
			
		||||
 | 
			
		||||
    let sketch =
 | 
			
		||||
        crate::std::sketch::inner_start_profile(sketch_surface, from_t, None, exec_state, args.clone()).await?;
 | 
			
		||||
@ -156,7 +156,7 @@ async fn inner_circle_three_point(
 | 
			
		||||
    exec_state: &mut ExecState,
 | 
			
		||||
    args: Args,
 | 
			
		||||
) -> Result<Sketch, KclError> {
 | 
			
		||||
    let ty = p1[0].ty.clone();
 | 
			
		||||
    let ty = p1[0].ty;
 | 
			
		||||
    let units = ty.expect_length();
 | 
			
		||||
 | 
			
		||||
    let p1 = point_to_len_unit(p1, units);
 | 
			
		||||
@ -172,10 +172,7 @@ async fn inner_circle_three_point(
 | 
			
		||||
        SketchOrSurface::Sketch(group) => group.on,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let from = [
 | 
			
		||||
        TyF64::new(center[0] + radius, ty.clone()),
 | 
			
		||||
        TyF64::new(center[1], ty.clone()),
 | 
			
		||||
    ];
 | 
			
		||||
    let from = [TyF64::new(center[0] + radius, ty), TyF64::new(center[1], ty)];
 | 
			
		||||
    let sketch =
 | 
			
		||||
        crate::std::sketch::inner_start_profile(sketch_surface, from.clone(), None, exec_state, args.clone()).await?;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -599,7 +599,7 @@ async fn inner_angled_line_of_x_length(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let to = get_y_component(Angle::from_degrees(angle_degrees), length.n);
 | 
			
		||||
    let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
 | 
			
		||||
    let to = [TyF64::new(to[0], length.ty), TyF64::new(to[1], length.ty)];
 | 
			
		||||
 | 
			
		||||
    let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
 | 
			
		||||
 | 
			
		||||
@ -666,7 +666,7 @@ async fn inner_angled_line_of_y_length(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let to = get_x_component(Angle::from_degrees(angle_degrees), length.n);
 | 
			
		||||
    let to = [TyF64::new(to[0], length.ty.clone()), TyF64::new(to[1], length.ty)];
 | 
			
		||||
    let to = [TyF64::new(to[0], length.ty), TyF64::new(to[1], length.ty)];
 | 
			
		||||
 | 
			
		||||
    let new_sketch = straight_line(StraightLineParams::relative(to, sketch, tag), exec_state, args).await?;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1941,3 +1941,24 @@ export fn subtract2d(
 | 
			
		||||
  /// The shape(s) which should be cut out of the sketch.
 | 
			
		||||
  tool: [Sketch; 1+],
 | 
			
		||||
): Sketch {}
 | 
			
		||||
 | 
			
		||||
/// Find the plane a face lies on.
 | 
			
		||||
/// Returns an error if the face doesn't lie on any plane (for example, the curved face of a cylinder)
 | 
			
		||||
///```kcl
 | 
			
		||||
/// triangle = startSketchOn(XY)
 | 
			
		||||
/// |> polygon(radius = 3, numSides = 3, center = [0, 0])
 | 
			
		||||
/// |> extrude(length = 2)
 | 
			
		||||
/// 
 | 
			
		||||
/// // Find the plane of the triangle's top face.
 | 
			
		||||
/// topPlane = planeOf(triangle, face = END)
 | 
			
		||||
/// 
 | 
			
		||||
/// // Create a new plane, 10 units above the triangle's top face.
 | 
			
		||||
/// startSketchOn(offsetPlane(topPlane, offset = 10))
 | 
			
		||||
/// ```
 | 
			
		||||
@(impl = std_rust)
 | 
			
		||||
export fn planeOf(
 | 
			
		||||
  /// The solid whose face is being queried.
 | 
			
		||||
  @solid: Solid,
 | 
			
		||||
  /// Find the plane which this face lies on.
 | 
			
		||||
  face: TaggedFace,
 | 
			
		||||
): Plane {}
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 20 KiB  | 
							
								
								
									
										381
									
								
								rust/kcl-lib/tests/plane_of/artifact_commands.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										381
									
								
								rust/kcl-lib/tests/plane_of/artifact_commands.snap
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,381 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Artifact commands plane_of.kcl
 | 
			
		||||
---
 | 
			
		||||
{
 | 
			
		||||
  "rust/kcl-lib/tests/plane_of/input.kcl": [
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "make_plane",
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "x_axis": {
 | 
			
		||||
          "x": 1.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "y_axis": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 1.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "size": 60.0,
 | 
			
		||||
        "clobber": false,
 | 
			
		||||
        "hide": true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "enable_sketch_mode",
 | 
			
		||||
        "entity_id": "[uuid]",
 | 
			
		||||
        "ortho": false,
 | 
			
		||||
        "animated": false,
 | 
			
		||||
        "adjust_camera": false,
 | 
			
		||||
        "planar_normal": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 1.0
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "start_path"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "move_path_pen",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "to": {
 | 
			
		||||
          "x": 2743.2,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "sketch_mode_disable"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": -1371.5999999999995,
 | 
			
		||||
            "y": 2375.680887661472,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": -1371.6000000000013,
 | 
			
		||||
            "y": -2375.680887661472,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": 2743.2,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "close_path",
 | 
			
		||||
        "path_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "enable_sketch_mode",
 | 
			
		||||
        "entity_id": "[uuid]",
 | 
			
		||||
        "ortho": false,
 | 
			
		||||
        "animated": false,
 | 
			
		||||
        "adjust_camera": false,
 | 
			
		||||
        "planar_normal": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 1.0
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extrude",
 | 
			
		||||
        "target": "[uuid]",
 | 
			
		||||
        "distance": 1828.8,
 | 
			
		||||
        "faces": null,
 | 
			
		||||
        "opposite": "None"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "sketch_mode_disable"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "object_bring_to_front",
 | 
			
		||||
        "object_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "solid3d_get_extrusion_face_info",
 | 
			
		||||
        "object_id": "[uuid]",
 | 
			
		||||
        "edge_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "solid3d_get_adjacency_info",
 | 
			
		||||
        "object_id": "[uuid]",
 | 
			
		||||
        "edge_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "face_is_planar",
 | 
			
		||||
        "object_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "make_plane",
 | 
			
		||||
        "origin": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 3657.6
 | 
			
		||||
        },
 | 
			
		||||
        "x_axis": {
 | 
			
		||||
          "x": 1.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "y_axis": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 1.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        },
 | 
			
		||||
        "size": 100.0,
 | 
			
		||||
        "clobber": false,
 | 
			
		||||
        "hide": false
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "plane_set_color",
 | 
			
		||||
        "plane_id": "[uuid]",
 | 
			
		||||
        "color": {
 | 
			
		||||
          "r": 0.6,
 | 
			
		||||
          "g": 0.6,
 | 
			
		||||
          "b": 0.6,
 | 
			
		||||
          "a": 0.3
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "object_visible",
 | 
			
		||||
        "object_id": "[uuid]",
 | 
			
		||||
        "hidden": true
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "enable_sketch_mode",
 | 
			
		||||
        "entity_id": "[uuid]",
 | 
			
		||||
        "ortho": false,
 | 
			
		||||
        "animated": false,
 | 
			
		||||
        "adjust_camera": false,
 | 
			
		||||
        "planar_normal": {
 | 
			
		||||
          "x": 0.0,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 1.0
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "start_path"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "move_path_pen",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "to": {
 | 
			
		||||
          "x": 1828.8,
 | 
			
		||||
          "y": 0.0,
 | 
			
		||||
          "z": 0.0
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "sketch_mode_disable"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": 0.00000000000011198170331403397,
 | 
			
		||||
            "y": 1828.8,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": -1828.8,
 | 
			
		||||
            "y": 0.00000000000022396340662806795,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": -0.0000000000003359451099421019,
 | 
			
		||||
            "y": -1828.8,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "extend_path",
 | 
			
		||||
        "path": "[uuid]",
 | 
			
		||||
        "segment": {
 | 
			
		||||
          "type": "line",
 | 
			
		||||
          "end": {
 | 
			
		||||
            "x": 1828.8,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0
 | 
			
		||||
          },
 | 
			
		||||
          "relative": false
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "cmdId": "[uuid]",
 | 
			
		||||
      "range": [],
 | 
			
		||||
      "command": {
 | 
			
		||||
        "type": "close_path",
 | 
			
		||||
        "path_id": "[uuid]"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "std::appearance": [],
 | 
			
		||||
  "std::array": [],
 | 
			
		||||
  "std::math": [],
 | 
			
		||||
  "std::prelude": [],
 | 
			
		||||
  "std::sketch": [],
 | 
			
		||||
  "std::solid": [],
 | 
			
		||||
  "std::sweep": [],
 | 
			
		||||
  "std::transform": [],
 | 
			
		||||
  "std::turns": [],
 | 
			
		||||
  "std::types": [],
 | 
			
		||||
  "std::units": []
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,6 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Artifact graph flowchart plane_of.kcl
 | 
			
		||||
extension: md
 | 
			
		||||
snapshot_kind: binary
 | 
			
		||||
---
 | 
			
		||||
							
								
								
									
										105
									
								
								rust/kcl-lib/tests/plane_of/artifact_graph_flowchart.snap.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								rust/kcl-lib/tests/plane_of/artifact_graph_flowchart.snap.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
			
		||||
```mermaid
 | 
			
		||||
flowchart LR
 | 
			
		||||
  subgraph path2 [Path]
 | 
			
		||||
    2["Path<br>[64, 114, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
 | 
			
		||||
    3["Segment<br>[64, 114, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
 | 
			
		||||
    4["Segment<br>[64, 114, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
 | 
			
		||||
    5["Segment<br>[64, 114, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
 | 
			
		||||
    6["Segment<br>[64, 114, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 1 }]
 | 
			
		||||
    7[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  subgraph path21 [Path]
 | 
			
		||||
    21["Path<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    22["Segment<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    23["Segment<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    24["Segment<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    25["Segment<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    26["Segment<br>[311, 361, 0]"]
 | 
			
		||||
      %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 1 }]
 | 
			
		||||
    27[Solid2d]
 | 
			
		||||
  end
 | 
			
		||||
  1["Plane<br>[41, 58, 0]"]
 | 
			
		||||
    %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 0 }]
 | 
			
		||||
  8["Sweep Extrusion<br>[120, 139, 0]"]
 | 
			
		||||
    %% [ProgramBodyItem { index: 0 }, VariableDeclarationDeclaration, VariableDeclarationInit, PipeBodyItem { index: 2 }]
 | 
			
		||||
  9[Wall]
 | 
			
		||||
    %% face_code_ref=Missing NodePath
 | 
			
		||||
  10[Wall]
 | 
			
		||||
    %% face_code_ref=Missing NodePath
 | 
			
		||||
  11[Wall]
 | 
			
		||||
    %% face_code_ref=Missing NodePath
 | 
			
		||||
  12["Cap Start"]
 | 
			
		||||
    %% face_code_ref=Missing NodePath
 | 
			
		||||
  13["Cap End"]
 | 
			
		||||
    %% face_code_ref=Missing NodePath
 | 
			
		||||
  14["SweepEdge Opposite"]
 | 
			
		||||
  15["SweepEdge Adjacent"]
 | 
			
		||||
  16["SweepEdge Opposite"]
 | 
			
		||||
  17["SweepEdge Adjacent"]
 | 
			
		||||
  18["SweepEdge Opposite"]
 | 
			
		||||
  19["SweepEdge Adjacent"]
 | 
			
		||||
  20["Plane<br>[277, 304, 0]"]
 | 
			
		||||
    %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 0 }, CallKwUnlabeledArg]
 | 
			
		||||
  28["StartSketchOnPlane<br>[263, 305, 0]"]
 | 
			
		||||
    %% [ProgramBodyItem { index: 2 }, ExpressionStatementExpr, PipeBodyItem { index: 0 }]
 | 
			
		||||
  1 --- 2
 | 
			
		||||
  2 --- 3
 | 
			
		||||
  2 --- 4
 | 
			
		||||
  2 --- 5
 | 
			
		||||
  2 --- 6
 | 
			
		||||
  2 --- 7
 | 
			
		||||
  2 ---- 8
 | 
			
		||||
  3 --- 9
 | 
			
		||||
  3 x--> 12
 | 
			
		||||
  3 --- 14
 | 
			
		||||
  3 --- 15
 | 
			
		||||
  4 --- 10
 | 
			
		||||
  4 x--> 12
 | 
			
		||||
  4 --- 16
 | 
			
		||||
  4 --- 17
 | 
			
		||||
  5 --- 11
 | 
			
		||||
  5 x--> 12
 | 
			
		||||
  5 --- 18
 | 
			
		||||
  5 --- 19
 | 
			
		||||
  8 --- 9
 | 
			
		||||
  8 --- 10
 | 
			
		||||
  8 --- 11
 | 
			
		||||
  8 --- 12
 | 
			
		||||
  8 --- 13
 | 
			
		||||
  8 --- 14
 | 
			
		||||
  8 --- 15
 | 
			
		||||
  8 --- 16
 | 
			
		||||
  8 --- 17
 | 
			
		||||
  8 --- 18
 | 
			
		||||
  8 --- 19
 | 
			
		||||
  9 --- 14
 | 
			
		||||
  9 --- 15
 | 
			
		||||
  19 <--x 9
 | 
			
		||||
  15 <--x 10
 | 
			
		||||
  10 --- 16
 | 
			
		||||
  10 --- 17
 | 
			
		||||
  17 <--x 11
 | 
			
		||||
  11 --- 18
 | 
			
		||||
  11 --- 19
 | 
			
		||||
  14 <--x 13
 | 
			
		||||
  16 <--x 13
 | 
			
		||||
  18 <--x 13
 | 
			
		||||
  20 --- 21
 | 
			
		||||
  20 <--x 28
 | 
			
		||||
  21 --- 22
 | 
			
		||||
  21 --- 23
 | 
			
		||||
  21 --- 24
 | 
			
		||||
  21 --- 25
 | 
			
		||||
  21 --- 26
 | 
			
		||||
  21 --- 27
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										705
									
								
								rust/kcl-lib/tests/plane_of/ast.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										705
									
								
								rust/kcl-lib/tests/plane_of/ast.snap
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,705 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Result of parsing plane_of.kcl
 | 
			
		||||
---
 | 
			
		||||
{
 | 
			
		||||
  "Ok": {
 | 
			
		||||
    "body": [
 | 
			
		||||
      {
 | 
			
		||||
        "commentStart": 0,
 | 
			
		||||
        "declaration": {
 | 
			
		||||
          "commentStart": 0,
 | 
			
		||||
          "end": 0,
 | 
			
		||||
          "id": {
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "name": "tri",
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "Identifier"
 | 
			
		||||
          },
 | 
			
		||||
          "init": {
 | 
			
		||||
            "body": [
 | 
			
		||||
              {
 | 
			
		||||
                "arguments": [],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "startSketchOn",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "XY",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name",
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "name": "radius",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "raw": "3",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 3.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "name": "numSides",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "raw": "3",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 3.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  },
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "name": "center",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "elements": [
 | 
			
		||||
                        {
 | 
			
		||||
                          "commentStart": 0,
 | 
			
		||||
                          "end": 0,
 | 
			
		||||
                          "moduleId": 0,
 | 
			
		||||
                          "raw": "0",
 | 
			
		||||
                          "start": 0,
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "value": {
 | 
			
		||||
                            "value": 0.0,
 | 
			
		||||
                            "suffix": "None"
 | 
			
		||||
                          }
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
                          "commentStart": 0,
 | 
			
		||||
                          "end": 0,
 | 
			
		||||
                          "moduleId": 0,
 | 
			
		||||
                          "raw": "0",
 | 
			
		||||
                          "start": 0,
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "type": "Literal",
 | 
			
		||||
                          "value": {
 | 
			
		||||
                            "value": 0.0,
 | 
			
		||||
                            "suffix": "None"
 | 
			
		||||
                          }
 | 
			
		||||
                        }
 | 
			
		||||
                      ],
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "ArrayExpression",
 | 
			
		||||
                      "type": "ArrayExpression"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "polygon",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": null
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "name": "length",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "raw": "2",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 2.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "extrude",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": null
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "nonCodeMeta": {
 | 
			
		||||
              "nonCodeNodes": {
 | 
			
		||||
                "2": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "NonCodeNode",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "type": "newLineBlockComment",
 | 
			
		||||
                      "value": "Get the plane which `tri` ends on.",
 | 
			
		||||
                      "style": "line"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ]
 | 
			
		||||
              },
 | 
			
		||||
              "startNodes": []
 | 
			
		||||
            },
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "PipeExpression",
 | 
			
		||||
            "type": "PipeExpression"
 | 
			
		||||
          },
 | 
			
		||||
          "moduleId": 0,
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "VariableDeclarator"
 | 
			
		||||
        },
 | 
			
		||||
        "end": 0,
 | 
			
		||||
        "kind": "const",
 | 
			
		||||
        "moduleId": 0,
 | 
			
		||||
        "start": 0,
 | 
			
		||||
        "type": "VariableDeclaration",
 | 
			
		||||
        "type": "VariableDeclaration"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "commentStart": 0,
 | 
			
		||||
        "declaration": {
 | 
			
		||||
          "commentStart": 0,
 | 
			
		||||
          "end": 0,
 | 
			
		||||
          "id": {
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "name": "p0",
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "Identifier"
 | 
			
		||||
          },
 | 
			
		||||
          "init": {
 | 
			
		||||
            "arguments": [
 | 
			
		||||
              {
 | 
			
		||||
                "type": "LabeledArg",
 | 
			
		||||
                "label": {
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": "face",
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                },
 | 
			
		||||
                "arg": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "END",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name",
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            ],
 | 
			
		||||
            "callee": {
 | 
			
		||||
              "abs_path": false,
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "name": {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "name": "planeOf",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Identifier"
 | 
			
		||||
              },
 | 
			
		||||
              "path": [],
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Name"
 | 
			
		||||
            },
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "CallExpressionKw",
 | 
			
		||||
            "type": "CallExpressionKw",
 | 
			
		||||
            "unlabeled": {
 | 
			
		||||
              "abs_path": false,
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "name": {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "name": "tri",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Identifier"
 | 
			
		||||
              },
 | 
			
		||||
              "path": [],
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Name",
 | 
			
		||||
              "type": "Name"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "moduleId": 0,
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "VariableDeclarator"
 | 
			
		||||
        },
 | 
			
		||||
        "end": 0,
 | 
			
		||||
        "kind": "const",
 | 
			
		||||
        "moduleId": 0,
 | 
			
		||||
        "start": 0,
 | 
			
		||||
        "type": "VariableDeclaration",
 | 
			
		||||
        "type": "VariableDeclaration"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "commentStart": 0,
 | 
			
		||||
        "end": 0,
 | 
			
		||||
        "expression": {
 | 
			
		||||
          "body": [
 | 
			
		||||
            {
 | 
			
		||||
              "arguments": [],
 | 
			
		||||
              "callee": {
 | 
			
		||||
                "abs_path": false,
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "name": {
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": "startSketchOn",
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                },
 | 
			
		||||
                "path": [],
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Name"
 | 
			
		||||
              },
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "CallExpressionKw",
 | 
			
		||||
              "type": "CallExpressionKw",
 | 
			
		||||
              "unlabeled": {
 | 
			
		||||
                "arguments": [
 | 
			
		||||
                  {
 | 
			
		||||
                    "type": "LabeledArg",
 | 
			
		||||
                    "label": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "name": "offset",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Identifier"
 | 
			
		||||
                    },
 | 
			
		||||
                    "arg": {
 | 
			
		||||
                      "commentStart": 0,
 | 
			
		||||
                      "end": 0,
 | 
			
		||||
                      "moduleId": 0,
 | 
			
		||||
                      "raw": "2",
 | 
			
		||||
                      "start": 0,
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "type": "Literal",
 | 
			
		||||
                      "value": {
 | 
			
		||||
                        "value": 2.0,
 | 
			
		||||
                        "suffix": "None"
 | 
			
		||||
                      }
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                ],
 | 
			
		||||
                "callee": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "offsetPlane",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                },
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "type": "CallExpressionKw",
 | 
			
		||||
                "unlabeled": {
 | 
			
		||||
                  "abs_path": false,
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "p0",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "path": [],
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Name",
 | 
			
		||||
                  "type": "Name"
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "arguments": [
 | 
			
		||||
                {
 | 
			
		||||
                  "type": "LabeledArg",
 | 
			
		||||
                  "label": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "radius",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "arg": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "raw": "2",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 2.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                  "type": "LabeledArg",
 | 
			
		||||
                  "label": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "numSides",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "arg": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "raw": "4",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "type": "Literal",
 | 
			
		||||
                    "value": {
 | 
			
		||||
                      "value": 4.0,
 | 
			
		||||
                      "suffix": "None"
 | 
			
		||||
                    }
 | 
			
		||||
                  }
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                  "type": "LabeledArg",
 | 
			
		||||
                  "label": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "name": "center",
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "Identifier"
 | 
			
		||||
                  },
 | 
			
		||||
                  "arg": {
 | 
			
		||||
                    "commentStart": 0,
 | 
			
		||||
                    "elements": [
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "moduleId": 0,
 | 
			
		||||
                        "raw": "0",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 0.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      },
 | 
			
		||||
                      {
 | 
			
		||||
                        "commentStart": 0,
 | 
			
		||||
                        "end": 0,
 | 
			
		||||
                        "moduleId": 0,
 | 
			
		||||
                        "raw": "0",
 | 
			
		||||
                        "start": 0,
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "type": "Literal",
 | 
			
		||||
                        "value": {
 | 
			
		||||
                          "value": 0.0,
 | 
			
		||||
                          "suffix": "None"
 | 
			
		||||
                        }
 | 
			
		||||
                      }
 | 
			
		||||
                    ],
 | 
			
		||||
                    "end": 0,
 | 
			
		||||
                    "moduleId": 0,
 | 
			
		||||
                    "start": 0,
 | 
			
		||||
                    "type": "ArrayExpression",
 | 
			
		||||
                    "type": "ArrayExpression"
 | 
			
		||||
                  }
 | 
			
		||||
                }
 | 
			
		||||
              ],
 | 
			
		||||
              "callee": {
 | 
			
		||||
                "abs_path": false,
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "name": {
 | 
			
		||||
                  "commentStart": 0,
 | 
			
		||||
                  "end": 0,
 | 
			
		||||
                  "moduleId": 0,
 | 
			
		||||
                  "name": "polygon",
 | 
			
		||||
                  "start": 0,
 | 
			
		||||
                  "type": "Identifier"
 | 
			
		||||
                },
 | 
			
		||||
                "path": [],
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Name"
 | 
			
		||||
              },
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "CallExpressionKw",
 | 
			
		||||
              "type": "CallExpressionKw",
 | 
			
		||||
              "unlabeled": null
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "commentStart": 0,
 | 
			
		||||
          "end": 0,
 | 
			
		||||
          "moduleId": 0,
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "PipeExpression",
 | 
			
		||||
          "type": "PipeExpression"
 | 
			
		||||
        },
 | 
			
		||||
        "moduleId": 0,
 | 
			
		||||
        "preComments": [
 | 
			
		||||
          "",
 | 
			
		||||
          "",
 | 
			
		||||
          "// Offset that plane by 2, then draw a square on it."
 | 
			
		||||
        ],
 | 
			
		||||
        "start": 0,
 | 
			
		||||
        "type": "ExpressionStatement",
 | 
			
		||||
        "type": "ExpressionStatement"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "commentStart": 0,
 | 
			
		||||
    "end": 0,
 | 
			
		||||
    "innerAttrs": [
 | 
			
		||||
      {
 | 
			
		||||
        "commentStart": 0,
 | 
			
		||||
        "end": 0,
 | 
			
		||||
        "moduleId": 0,
 | 
			
		||||
        "name": {
 | 
			
		||||
          "commentStart": 0,
 | 
			
		||||
          "end": 0,
 | 
			
		||||
          "moduleId": 0,
 | 
			
		||||
          "name": "settings",
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "Identifier"
 | 
			
		||||
        },
 | 
			
		||||
        "properties": [
 | 
			
		||||
          {
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "key": {
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "name": "defaultLengthUnit",
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Identifier"
 | 
			
		||||
            },
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "ObjectProperty",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "abs_path": false,
 | 
			
		||||
              "commentStart": 0,
 | 
			
		||||
              "end": 0,
 | 
			
		||||
              "moduleId": 0,
 | 
			
		||||
              "name": {
 | 
			
		||||
                "commentStart": 0,
 | 
			
		||||
                "end": 0,
 | 
			
		||||
                "moduleId": 0,
 | 
			
		||||
                "name": "yd",
 | 
			
		||||
                "start": 0,
 | 
			
		||||
                "type": "Identifier"
 | 
			
		||||
              },
 | 
			
		||||
              "path": [],
 | 
			
		||||
              "start": 0,
 | 
			
		||||
              "type": "Name",
 | 
			
		||||
              "type": "Name"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "start": 0,
 | 
			
		||||
        "type": "Annotation"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "moduleId": 0,
 | 
			
		||||
    "nonCodeMeta": {
 | 
			
		||||
      "nonCodeNodes": {
 | 
			
		||||
        "2": [
 | 
			
		||||
          {
 | 
			
		||||
            "commentStart": 0,
 | 
			
		||||
            "end": 0,
 | 
			
		||||
            "moduleId": 0,
 | 
			
		||||
            "start": 0,
 | 
			
		||||
            "type": "NonCodeNode",
 | 
			
		||||
            "value": {
 | 
			
		||||
              "type": "newLine"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "startNodes": [
 | 
			
		||||
        {
 | 
			
		||||
          "commentStart": 0,
 | 
			
		||||
          "end": 0,
 | 
			
		||||
          "moduleId": 0,
 | 
			
		||||
          "start": 0,
 | 
			
		||||
          "type": "NonCodeNode",
 | 
			
		||||
          "value": {
 | 
			
		||||
            "type": "newLine"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    "start": 0
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								rust/kcl-lib/tests/plane_of/input.kcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								rust/kcl-lib/tests/plane_of/input.kcl
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
@settings(defaultLengthUnit = yd)
 | 
			
		||||
 | 
			
		||||
tri = startSketchOn(XY)
 | 
			
		||||
  |> polygon(radius = 3, numSides = 3, center = [0, 0])
 | 
			
		||||
  |> extrude(length = 2)
 | 
			
		||||
 | 
			
		||||
// Get the plane which `tri` ends on.
 | 
			
		||||
p0 = planeOf(tri, face = END)
 | 
			
		||||
 | 
			
		||||
// Offset that plane by 2, then draw a square on it.
 | 
			
		||||
startSketchOn(offsetPlane(p0, offset = 2))
 | 
			
		||||
  |> polygon(radius = 2, numSides = 4, center = [0, 0])
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										254
									
								
								rust/kcl-lib/tests/plane_of/ops.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								rust/kcl-lib/tests/plane_of/ops.snap
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,254 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Operations executed plane_of.kcl
 | 
			
		||||
---
 | 
			
		||||
{
 | 
			
		||||
  "rust/kcl-lib/tests/plane_of/input.kcl": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "StdLibCall",
 | 
			
		||||
      "name": "startSketchOn",
 | 
			
		||||
      "unlabeledArg": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "labeledArgs": {},
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ProgramBodyItem",
 | 
			
		||||
            "index": 0
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "VariableDeclarationDeclaration"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "VariableDeclarationInit"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "PipeBodyItem",
 | 
			
		||||
            "index": 0
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "StdLibCall",
 | 
			
		||||
      "name": "extrude",
 | 
			
		||||
      "unlabeledArg": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Sketch",
 | 
			
		||||
          "value": {
 | 
			
		||||
            "artifactId": "[uuid]"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "labeledArgs": {
 | 
			
		||||
        "length": {
 | 
			
		||||
          "value": {
 | 
			
		||||
            "type": "Number",
 | 
			
		||||
            "value": 2.0,
 | 
			
		||||
            "ty": {
 | 
			
		||||
              "type": "Default",
 | 
			
		||||
              "len": {
 | 
			
		||||
                "type": "Yards"
 | 
			
		||||
              },
 | 
			
		||||
              "angle": {
 | 
			
		||||
                "type": "Degrees"
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "sourceRange": []
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ProgramBodyItem",
 | 
			
		||||
            "index": 0
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "VariableDeclarationDeclaration"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "VariableDeclarationInit"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "PipeBodyItem",
 | 
			
		||||
            "index": 2
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "StdLibCall",
 | 
			
		||||
      "name": "offsetPlane",
 | 
			
		||||
      "unlabeledArg": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "labeledArgs": {
 | 
			
		||||
        "offset": {
 | 
			
		||||
          "value": {
 | 
			
		||||
            "type": "Number",
 | 
			
		||||
            "value": 2.0,
 | 
			
		||||
            "ty": {
 | 
			
		||||
              "type": "Default",
 | 
			
		||||
              "len": {
 | 
			
		||||
                "type": "Yards"
 | 
			
		||||
              },
 | 
			
		||||
              "angle": {
 | 
			
		||||
                "type": "Degrees"
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "sourceRange": []
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ProgramBodyItem",
 | 
			
		||||
            "index": 2
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ExpressionStatementExpr"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "PipeBodyItem",
 | 
			
		||||
            "index": 0
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "CallKwUnlabeledArg"
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "StdLibCall",
 | 
			
		||||
      "name": "startSketchOn",
 | 
			
		||||
      "unlabeledArg": {
 | 
			
		||||
        "value": {
 | 
			
		||||
          "type": "Plane",
 | 
			
		||||
          "artifact_id": "[uuid]"
 | 
			
		||||
        },
 | 
			
		||||
        "sourceRange": []
 | 
			
		||||
      },
 | 
			
		||||
      "labeledArgs": {},
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": [
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ProgramBodyItem",
 | 
			
		||||
            "index": 2
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "ExpressionStatementExpr"
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "type": "PipeBodyItem",
 | 
			
		||||
            "index": 0
 | 
			
		||||
          }
 | 
			
		||||
        ]
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "std::appearance": [],
 | 
			
		||||
  "std::array": [],
 | 
			
		||||
  "std::math": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "VariableDeclaration",
 | 
			
		||||
      "name": "PI",
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Number",
 | 
			
		||||
        "value": 3.141592653589793,
 | 
			
		||||
        "ty": {
 | 
			
		||||
          "type": "Unknown"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "visibility": "export",
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": []
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "VariableDeclaration",
 | 
			
		||||
      "name": "E",
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Number",
 | 
			
		||||
        "value": 2.718281828459045,
 | 
			
		||||
        "ty": {
 | 
			
		||||
          "type": "Known",
 | 
			
		||||
          "type": "Count"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "visibility": "export",
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": []
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "VariableDeclaration",
 | 
			
		||||
      "name": "TAU",
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "Number",
 | 
			
		||||
        "value": 6.283185307179586,
 | 
			
		||||
        "ty": {
 | 
			
		||||
          "type": "Known",
 | 
			
		||||
          "type": "Count"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "visibility": "export",
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": []
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "std::prelude": [
 | 
			
		||||
    {
 | 
			
		||||
      "type": "VariableDeclaration",
 | 
			
		||||
      "name": "START",
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "String",
 | 
			
		||||
        "value": "start"
 | 
			
		||||
      },
 | 
			
		||||
      "visibility": "export",
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": []
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "type": "VariableDeclaration",
 | 
			
		||||
      "name": "END",
 | 
			
		||||
      "value": {
 | 
			
		||||
        "type": "String",
 | 
			
		||||
        "value": "end"
 | 
			
		||||
      },
 | 
			
		||||
      "visibility": "export",
 | 
			
		||||
      "nodePath": {
 | 
			
		||||
        "steps": []
 | 
			
		||||
      },
 | 
			
		||||
      "sourceRange": []
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "std::sketch": [],
 | 
			
		||||
  "std::solid": [],
 | 
			
		||||
  "std::sweep": [],
 | 
			
		||||
  "std::transform": [],
 | 
			
		||||
  "std::turns": [],
 | 
			
		||||
  "std::types": [],
 | 
			
		||||
  "std::units": []
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										192
									
								
								rust/kcl-lib/tests/plane_of/program_memory.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								rust/kcl-lib/tests/plane_of/program_memory.snap
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,192 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Variables in memory after executing plane_of.kcl
 | 
			
		||||
---
 | 
			
		||||
{
 | 
			
		||||
  "p0": {
 | 
			
		||||
    "type": "Plane",
 | 
			
		||||
    "value": {
 | 
			
		||||
      "artifactId": "[uuid]",
 | 
			
		||||
      "id": "[uuid]",
 | 
			
		||||
      "origin": {
 | 
			
		||||
        "x": 0.0,
 | 
			
		||||
        "y": 0.0,
 | 
			
		||||
        "z": 1828.8,
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "value": "Uninit",
 | 
			
		||||
      "xAxis": {
 | 
			
		||||
        "x": 1.0,
 | 
			
		||||
        "y": 0.0,
 | 
			
		||||
        "z": 0.0,
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "yAxis": {
 | 
			
		||||
        "x": 0.0,
 | 
			
		||||
        "y": 1.0,
 | 
			
		||||
        "z": 0.0,
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Mm"
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "tri": {
 | 
			
		||||
    "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"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "sketch": {
 | 
			
		||||
        "type": "Sketch",
 | 
			
		||||
        "id": "[uuid]",
 | 
			
		||||
        "paths": [
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              3.0,
 | 
			
		||||
              0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -1.4999999999999993,
 | 
			
		||||
              2.598076211353316
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Yards"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -1.4999999999999993,
 | 
			
		||||
              2.598076211353316
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              -1.5000000000000013,
 | 
			
		||||
              -2.5980762113533156
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Yards"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            "__geoMeta": {
 | 
			
		||||
              "id": "[uuid]",
 | 
			
		||||
              "sourceRange": []
 | 
			
		||||
            },
 | 
			
		||||
            "from": [
 | 
			
		||||
              -1.5000000000000013,
 | 
			
		||||
              -2.5980762113533156
 | 
			
		||||
            ],
 | 
			
		||||
            "tag": null,
 | 
			
		||||
            "to": [
 | 
			
		||||
              3.0,
 | 
			
		||||
              0.0
 | 
			
		||||
            ],
 | 
			
		||||
            "type": "ToPoint",
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Yards"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        ],
 | 
			
		||||
        "on": {
 | 
			
		||||
          "artifactId": "[uuid]",
 | 
			
		||||
          "id": "[uuid]",
 | 
			
		||||
          "origin": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0,
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Mm"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "type": "plane",
 | 
			
		||||
          "value": "XY",
 | 
			
		||||
          "xAxis": {
 | 
			
		||||
            "x": 1.0,
 | 
			
		||||
            "y": 0.0,
 | 
			
		||||
            "z": 0.0,
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Unknown"
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          "yAxis": {
 | 
			
		||||
            "x": 0.0,
 | 
			
		||||
            "y": 1.0,
 | 
			
		||||
            "z": 0.0,
 | 
			
		||||
            "units": {
 | 
			
		||||
              "type": "Unknown"
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "start": {
 | 
			
		||||
          "from": [
 | 
			
		||||
            3.0,
 | 
			
		||||
            0.0
 | 
			
		||||
          ],
 | 
			
		||||
          "to": [
 | 
			
		||||
            3.0,
 | 
			
		||||
            0.0
 | 
			
		||||
          ],
 | 
			
		||||
          "units": {
 | 
			
		||||
            "type": "Yards"
 | 
			
		||||
          },
 | 
			
		||||
          "tag": null,
 | 
			
		||||
          "__geoMeta": {
 | 
			
		||||
            "id": "[uuid]",
 | 
			
		||||
            "sourceRange": []
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "artifactId": "[uuid]",
 | 
			
		||||
        "originalId": "[uuid]",
 | 
			
		||||
        "units": {
 | 
			
		||||
          "type": "Yards"
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "height": 2.0,
 | 
			
		||||
      "startCapId": "[uuid]",
 | 
			
		||||
      "endCapId": "[uuid]",
 | 
			
		||||
      "units": {
 | 
			
		||||
        "type": "Yards"
 | 
			
		||||
      },
 | 
			
		||||
      "sectional": false
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								rust/kcl-lib/tests/plane_of/rendered_model.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								rust/kcl-lib/tests/plane_of/rendered_model.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 53 KiB  | 
							
								
								
									
										16
									
								
								rust/kcl-lib/tests/plane_of/unparsed.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								rust/kcl-lib/tests/plane_of/unparsed.snap
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
---
 | 
			
		||||
source: kcl-lib/src/simulation_tests.rs
 | 
			
		||||
description: Result of unparsing plane_of.kcl
 | 
			
		||||
---
 | 
			
		||||
@settings(defaultLengthUnit = yd)
 | 
			
		||||
 | 
			
		||||
tri = startSketchOn(XY)
 | 
			
		||||
  |> polygon(radius = 3, numSides = 3, center = [0, 0])
 | 
			
		||||
  |> extrude(length = 2)
 | 
			
		||||
 | 
			
		||||
// Get the plane which `tri` ends on.
 | 
			
		||||
p0 = planeOf(tri, face = END)
 | 
			
		||||
 | 
			
		||||
// Offset that plane by 2, then draw a square on it.
 | 
			
		||||
startSketchOn(offsetPlane(p0, offset = 2))
 | 
			
		||||
  |> polygon(radius = 2, numSides = 4, center = [0, 0])
 | 
			
		||||
		Reference in New Issue
	
	Block a user