kcl_lib/std/
planes.rs

1//! Standard library plane helpers.
2
3use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Color, ModelingCmd};
4use kittycad_modeling_cmds as kcmc;
5
6use super::{args::TyF64, sketch::PlaneData};
7use crate::{
8    errors::KclError,
9    execution::{types::RuntimeType, ExecState, KclValue, Plane, PlaneType},
10    std::Args,
11};
12
13/// Offset a plane by a distance along its normal.
14pub async fn offset_plane(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
15    let std_plane = args.get_unlabeled_kw_arg("plane")?;
16    let offset: TyF64 = args.get_kw_arg_typed("offset", &RuntimeType::length(), exec_state)?;
17    let plane = inner_offset_plane(std_plane, offset, exec_state, &args).await?;
18    Ok(KclValue::Plane { value: Box::new(plane) })
19}
20
21async fn inner_offset_plane(
22    plane: PlaneData,
23    offset: TyF64,
24    exec_state: &mut ExecState,
25    args: &Args,
26) -> Result<Plane, KclError> {
27    let mut plane = Plane::from_plane_data(plane, exec_state)?;
28    // Though offset planes might be derived from standard planes, they are not
29    // standard planes themselves.
30    plane.value = PlaneType::Custom;
31
32    let normal = plane.info.x_axis.axes_cross_product(&plane.info.y_axis);
33    plane.info.origin += normal * offset.to_length_units(plane.info.origin.units);
34    make_offset_plane_in_engine(&plane, exec_state, args).await?;
35
36    Ok(plane)
37}
38
39// Engine-side effectful creation of an actual plane object.
40// offset planes are shown by default, and hidden by default if they
41// are used as a sketch plane. That hiding command is sent within inner_start_profile_at
42async fn make_offset_plane_in_engine(plane: &Plane, exec_state: &mut ExecState, args: &Args) -> Result<(), KclError> {
43    // Create new default planes.
44    let default_size = 100.0;
45    let color = Color {
46        r: 0.6,
47        g: 0.6,
48        b: 0.6,
49        a: 0.3,
50    };
51
52    args.batch_modeling_cmd(
53        plane.id,
54        ModelingCmd::from(mcmd::MakePlane {
55            clobber: false,
56            origin: plane.info.origin.into(),
57            size: LengthUnit(default_size),
58            x_axis: plane.info.x_axis.into(),
59            y_axis: plane.info.y_axis.into(),
60            hide: Some(false),
61        }),
62    )
63    .await?;
64
65    // Set the color.
66    args.batch_modeling_cmd(
67        exec_state.next_uuid(),
68        ModelingCmd::from(mcmd::PlaneSetColor {
69            color,
70            plane_id: plane.id,
71        }),
72    )
73    .await?;
74
75    Ok(())
76}