1use 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
13pub 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 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
39async fn make_offset_plane_in_engine(plane: &Plane, exec_state: &mut ExecState, args: &Args) -> Result<(), KclError> {
43 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 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}