2024-09-25 16:12:18 -07:00
|
|
|
//! Standard library mirror.
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
use kcmc::{each_cmd as mcmd, ModelingCmd};
|
2025-04-03 22:44:52 +13:00
|
|
|
use kittycad_modeling_cmds::{self as kcmc, length_unit::LengthUnit, shared::Point3d};
|
2024-09-25 16:12:18 -07:00
|
|
|
|
|
|
|
use crate::{
|
|
|
|
errors::KclError,
|
2025-04-03 22:44:52 +13:00
|
|
|
execution::{
|
|
|
|
types::{PrimitiveType, RuntimeType},
|
|
|
|
ExecState, KclValue, Sketch,
|
|
|
|
},
|
2025-01-07 19:10:53 -08:00
|
|
|
std::{axis_or_reference::Axis2dOrEdgeReference, Args},
|
2024-09-25 16:12:18 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Mirror a sketch.
|
|
|
|
///
|
|
|
|
/// Only works on unclosed sketches for now.
|
|
|
|
pub async fn mirror_2d(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
2025-04-03 22:44:52 +13:00
|
|
|
let sketches = args.get_unlabeled_kw_arg_typed("sketches", &RuntimeType::sketches(), exec_state)?;
|
|
|
|
let axis = args.get_kw_arg_typed(
|
|
|
|
"axis",
|
|
|
|
&RuntimeType::Union(vec![
|
|
|
|
RuntimeType::Primitive(PrimitiveType::Edge),
|
|
|
|
RuntimeType::Primitive(PrimitiveType::Axis2d),
|
|
|
|
]),
|
|
|
|
exec_state,
|
|
|
|
)?;
|
2024-09-25 16:12:18 -07:00
|
|
|
|
2025-04-03 22:44:52 +13:00
|
|
|
let sketches = inner_mirror_2d(sketches, axis, exec_state, args).await?;
|
2024-09-27 15:44:44 -07:00
|
|
|
Ok(sketches.into())
|
2024-09-25 16:12:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn inner_mirror_2d(
|
2025-03-17 17:57:26 +13:00
|
|
|
sketches: Vec<Sketch>,
|
2025-04-03 22:44:52 +13:00
|
|
|
axis: Axis2dOrEdgeReference,
|
2024-09-25 16:12:18 -07:00
|
|
|
exec_state: &mut ExecState,
|
|
|
|
args: Args,
|
2025-03-17 17:57:26 +13:00
|
|
|
) -> Result<Vec<Sketch>, KclError> {
|
|
|
|
let starting_sketches = sketches;
|
2024-09-25 16:12:18 -07:00
|
|
|
|
2025-02-18 13:50:13 -08:00
|
|
|
if args.ctx.no_engine_commands().await {
|
2024-09-27 15:44:44 -07:00
|
|
|
return Ok(starting_sketches);
|
2024-09-25 16:12:18 -07:00
|
|
|
}
|
|
|
|
|
2025-04-03 22:44:52 +13:00
|
|
|
match axis {
|
|
|
|
Axis2dOrEdgeReference::Axis { direction, origin } => {
|
2024-09-25 16:12:18 -07:00
|
|
|
args.batch_modeling_cmd(
|
2024-12-17 09:38:32 +13:00
|
|
|
exec_state.next_uuid(),
|
2024-09-25 16:12:18 -07:00
|
|
|
ModelingCmd::from(mcmd::EntityMirror {
|
2024-09-27 15:44:44 -07:00
|
|
|
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
2025-04-03 22:44:52 +13:00
|
|
|
axis: Point3d {
|
|
|
|
x: direction[0],
|
|
|
|
y: direction[1],
|
|
|
|
z: 0.0,
|
|
|
|
},
|
|
|
|
point: Point3d {
|
|
|
|
x: LengthUnit(origin[0]),
|
|
|
|
y: LengthUnit(origin[1]),
|
|
|
|
z: LengthUnit(0.0),
|
|
|
|
},
|
2024-09-25 16:12:18 -07:00
|
|
|
}),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
}
|
2025-01-07 19:10:53 -08:00
|
|
|
Axis2dOrEdgeReference::Edge(edge) => {
|
2024-09-25 16:12:18 -07:00
|
|
|
let edge_id = edge.get_engine_id(exec_state, &args)?;
|
|
|
|
|
|
|
|
args.batch_modeling_cmd(
|
2024-12-17 09:38:32 +13:00
|
|
|
exec_state.next_uuid(),
|
2024-09-25 16:12:18 -07:00
|
|
|
ModelingCmd::from(mcmd::EntityMirrorAcrossEdge {
|
2024-09-27 15:44:44 -07:00
|
|
|
ids: starting_sketches.iter().map(|sketch| sketch.id).collect(),
|
2024-09-25 16:12:18 -07:00
|
|
|
edge_id,
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
.await?;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-09-27 15:44:44 -07:00
|
|
|
Ok(starting_sketches)
|
2024-09-25 16:12:18 -07:00
|
|
|
}
|