Files
modeling-app/rust/kcl-lib/src/std/shell.rs

127 lines
4.0 KiB
Rust
Raw Normal View History

//! Standard library shells.
use anyhow::Result;
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
use kittycad_modeling_cmds as kcmc;
use super::args::TyF64;
use crate::{
errors::{KclError, KclErrorDetails},
execution::{
types::{ArrayLen, RuntimeType},
ExecState, KclValue, Solid,
},
std::{sketch::FaceTag, Args},
};
/// Create a shell.
pub async fn shell(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
let solids = args.get_unlabeled_kw_arg_typed("solids", &RuntimeType::solids(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?;
let faces = args.get_kw_arg_typed(
"faces",
&RuntimeType::Array(Box::new(RuntimeType::tag()), ArrayLen::Minimum(1)),
exec_state,
)?;
let result = inner_shell(solids, thickness, faces, exec_state, args).await?;
Ok(result.into())
}
async fn inner_shell(
solids: Vec<Solid>,
thickness: TyF64,
faces: Vec<FaceTag>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Solid>, KclError> {
if faces.is_empty() {
return Err(KclError::new_type(KclErrorDetails::new(
"You must shell at least one face".to_owned(),
vec![args.source_range],
)));
}
if solids.is_empty() {
return Err(KclError::new_type(KclErrorDetails::new(
"You must shell at least one solid".to_owned(),
vec![args.source_range],
)));
}
let mut face_ids = Vec::new();
for solid in &solids {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solids(exec_state, &[solid.clone()]).await?;
for tag in &faces {
let extrude_plane_id = tag.get_face_id(solid, exec_state, &args, false).await?;
face_ids.push(extrude_plane_id);
}
}
if face_ids.is_empty() {
return Err(KclError::new_type(KclErrorDetails::new(
"Expected at least one valid face".to_owned(),
vec![args.source_range],
)));
}
// Make sure all the solids have the same id, as we are going to shell them all at
// once.
if !solids.iter().all(|eg| eg.id == solids[0].id) {
return Err(KclError::new_type(KclErrorDetails::new(
"All solids stem from the same root object, like multiple sketch on face extrusions, etc.".to_owned(),
vec![args.source_range],
)));
}
get responses back from batch (#2687) * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove my stupid println Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * weird typescript Signed-off-by: Jess Frazelle <github@jessfraz.com> * better batch stuff; Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * ckeanup Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * typpo Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * batch more Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * thing * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * up[dates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixces Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanups Signed-off-by: Jess Frazelle <github@jessfraz.com> * images Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * empty * cleanups Signed-off-by: Jess Frazelle <github@jessfraz.com> * console log all the things Signed-off-by: Jess Frazelle <github@jessfraz.com> * A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu) * fixups Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * console log cleanup Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * nicer types Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove logs Signed-off-by: Jess Frazelle <github@jessfraz.com> * remove logs Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-06-19 13:57:50 -07:00
args.batch_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::Solid3dShellFace {
hollow: false,
face_ids,
object_id: solids[0].id,
shell_thickness: LengthUnit(thickness.to_mm()),
}),
)
.await?;
Ok(solids)
}
/// Make the inside of a 3D object hollow.
pub async fn hollow(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
2025-04-23 13:35:33 -05:00
let solid = args.get_unlabeled_kw_arg_typed("solid", &RuntimeType::solid(), exec_state)?;
let thickness: TyF64 = args.get_kw_arg_typed("thickness", &RuntimeType::length(), exec_state)?;
2025-04-23 13:35:33 -05:00
let value = inner_hollow(solid, thickness, exec_state, args).await?;
Ok(KclValue::Solid { value })
}
async fn inner_hollow(
solid: Box<Solid>,
2025-04-23 13:35:33 -05:00
thickness: TyF64,
exec_state: &mut ExecState,
args: Args,
) -> Result<Box<Solid>, KclError> {
// Flush the batch for our fillets/chamfers if there are any.
// If we do not do these for sketch on face, things will fail with face does not exist.
args.flush_batch_for_solids(exec_state, &[(*solid).clone()]).await?;
args.batch_modeling_cmd(
exec_state.next_uuid(),
ModelingCmd::from(mcmd::Solid3dShellFace {
hollow: true,
face_ids: Vec::new(), // This is empty because we want to hollow the entire object.
object_id: solid.id,
shell_thickness: LengthUnit(thickness.to_mm()),
}),
)
.await?;
Ok(solid)
}