Allow the origin of rotation to be specified (#7608)
* pass axis origin to endpoint * fmt * fix lint errors * update sim tests with new transform endpoint * added missed files * revert cargo.toml * implement review requests * fmt * revert unnecessary custom origin
This commit is contained in:
@ -58,4 +58,11 @@ impl Axis3dOrPoint3d {
|
||||
Axis3dOrPoint3d::Point(point) => point.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis_origin(&self) -> Option<[TyF64; 3]> {
|
||||
match self {
|
||||
Axis3dOrPoint3d::Axis { origin, .. } => Some(origin.clone()),
|
||||
Axis3dOrPoint3d::Point(..) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use kcmc::{
|
||||
ModelingCmd, each_cmd as mcmd,
|
||||
length_unit::LengthUnit,
|
||||
shared,
|
||||
shared::{Point3d, Point4d},
|
||||
shared::{OriginType, Point3d},
|
||||
};
|
||||
use kittycad_modeling_cmds as kcmc;
|
||||
|
||||
@ -18,6 +18,16 @@ use crate::{
|
||||
std::{Args, args::TyF64, axis_or_reference::Axis3dOrPoint3d},
|
||||
};
|
||||
|
||||
fn transform_by<T>(property: T, set: bool, is_local: bool, origin: Option<OriginType>) -> shared::TransformBy<T> {
|
||||
shared::TransformBy {
|
||||
property,
|
||||
set,
|
||||
#[expect(deprecated)]
|
||||
is_local,
|
||||
origin,
|
||||
}
|
||||
}
|
||||
|
||||
/// Scale a solid or a sketch.
|
||||
pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||
let objects = args.get_unlabeled_kw_arg(
|
||||
@ -70,6 +80,13 @@ async fn inner_scale(
|
||||
exec_state.flush_batch_for_solids((&args).into(), solids).await?;
|
||||
}
|
||||
|
||||
let is_global = global.unwrap_or(false);
|
||||
let origin = if is_global {
|
||||
Some(OriginType::Global)
|
||||
} else {
|
||||
Some(OriginType::Local)
|
||||
};
|
||||
|
||||
let mut objects = objects.clone();
|
||||
for object_id in objects.ids(&args.ctx).await? {
|
||||
exec_state
|
||||
@ -78,15 +95,16 @@ async fn inner_scale(
|
||||
ModelingCmd::from(mcmd::SetObjectTransform {
|
||||
object_id,
|
||||
transforms: vec![shared::ComponentTransform {
|
||||
scale: Some(shared::TransformBy::<Point3d<f64>> {
|
||||
property: Point3d {
|
||||
scale: Some(transform_by(
|
||||
Point3d {
|
||||
x: x.unwrap_or(1.0),
|
||||
y: y.unwrap_or(1.0),
|
||||
z: z.unwrap_or(1.0),
|
||||
},
|
||||
set: false,
|
||||
is_local: !global.unwrap_or(false),
|
||||
}),
|
||||
false,
|
||||
!is_global,
|
||||
origin,
|
||||
)),
|
||||
translate: None,
|
||||
rotate_rpy: None,
|
||||
rotate_angle_axis: None,
|
||||
@ -142,6 +160,13 @@ async fn inner_translate(
|
||||
exec_state.flush_batch_for_solids((&args).into(), solids).await?;
|
||||
}
|
||||
|
||||
let is_global = global.unwrap_or(false);
|
||||
let origin = if is_global {
|
||||
Some(OriginType::Global)
|
||||
} else {
|
||||
Some(OriginType::Local)
|
||||
};
|
||||
|
||||
let mut objects = objects.clone();
|
||||
for object_id in objects.ids(&args.ctx).await? {
|
||||
exec_state
|
||||
@ -150,15 +175,16 @@ async fn inner_translate(
|
||||
ModelingCmd::from(mcmd::SetObjectTransform {
|
||||
object_id,
|
||||
transforms: vec![shared::ComponentTransform {
|
||||
translate: Some(shared::TransformBy::<Point3d<LengthUnit>> {
|
||||
property: shared::Point3d {
|
||||
translate: Some(transform_by(
|
||||
shared::Point3d {
|
||||
x: LengthUnit(x.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||
y: LengthUnit(y.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||
z: LengthUnit(z.as_ref().map(|t| t.to_mm()).unwrap_or_default()),
|
||||
},
|
||||
set: false,
|
||||
is_local: !global.unwrap_or(false),
|
||||
}),
|
||||
false,
|
||||
!is_global,
|
||||
origin,
|
||||
)),
|
||||
scale: None,
|
||||
rotate_rpy: None,
|
||||
rotate_angle_axis: None,
|
||||
@ -193,6 +219,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
]),
|
||||
exec_state,
|
||||
)?;
|
||||
let origin = axis.clone().map(|a| a.axis_origin()).unwrap_or_default();
|
||||
let axis = axis.map(|a| a.to_point3d());
|
||||
let angle: Option<TyF64> = args.get_kw_arg_opt("angle", &RuntimeType::degrees(), exec_state)?;
|
||||
let global = args.get_kw_arg_opt("global", &RuntimeType::bool(), exec_state)?;
|
||||
@ -286,6 +313,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
|
||||
// Don't adjust axis units since the axis must be normalized and only the direction
|
||||
// should be significant, not the magnitude.
|
||||
axis.map(|a| [a[0].n, a[1].n, a[2].n]),
|
||||
origin.map(|a| [a[0].n, a[1].n, a[2].n]),
|
||||
angle.map(|t| t.n),
|
||||
global,
|
||||
exec_state,
|
||||
@ -302,6 +330,7 @@ async fn inner_rotate(
|
||||
pitch: Option<f64>,
|
||||
yaw: Option<f64>,
|
||||
axis: Option<[f64; 3]>,
|
||||
origin: Option<[f64; 3]>,
|
||||
angle: Option<f64>,
|
||||
global: Option<bool>,
|
||||
exec_state: &mut ExecState,
|
||||
@ -313,6 +342,20 @@ async fn inner_rotate(
|
||||
exec_state.flush_batch_for_solids((&args).into(), solids).await?;
|
||||
}
|
||||
|
||||
let origin = if let Some(origin) = origin {
|
||||
Some(OriginType::Custom {
|
||||
origin: shared::Point3d {
|
||||
x: origin[0],
|
||||
y: origin[1],
|
||||
z: origin[2],
|
||||
},
|
||||
})
|
||||
} else if global.unwrap_or(false) {
|
||||
Some(OriginType::Global)
|
||||
} else {
|
||||
Some(OriginType::Local)
|
||||
};
|
||||
|
||||
let mut objects = objects.clone();
|
||||
for object_id in objects.ids(&args.ctx).await? {
|
||||
if let (Some(axis), Some(angle)) = (&axis, angle) {
|
||||
@ -322,16 +365,17 @@ async fn inner_rotate(
|
||||
ModelingCmd::from(mcmd::SetObjectTransform {
|
||||
object_id,
|
||||
transforms: vec![shared::ComponentTransform {
|
||||
rotate_angle_axis: Some(shared::TransformBy::<Point4d<f64>> {
|
||||
property: shared::Point4d {
|
||||
rotate_angle_axis: Some(transform_by(
|
||||
shared::Point4d {
|
||||
x: axis[0],
|
||||
y: axis[1],
|
||||
z: axis[2],
|
||||
w: angle,
|
||||
},
|
||||
set: false,
|
||||
is_local: !global.unwrap_or(false),
|
||||
}),
|
||||
false,
|
||||
!global.unwrap_or(false),
|
||||
origin,
|
||||
)),
|
||||
scale: None,
|
||||
rotate_rpy: None,
|
||||
translate: None,
|
||||
@ -347,15 +391,16 @@ async fn inner_rotate(
|
||||
ModelingCmd::from(mcmd::SetObjectTransform {
|
||||
object_id,
|
||||
transforms: vec![shared::ComponentTransform {
|
||||
rotate_rpy: Some(shared::TransformBy::<Point3d<f64>> {
|
||||
property: shared::Point3d {
|
||||
rotate_rpy: Some(transform_by(
|
||||
shared::Point3d {
|
||||
x: roll.unwrap_or(0.0),
|
||||
y: pitch.unwrap_or(0.0),
|
||||
z: yaw.unwrap_or(0.0),
|
||||
},
|
||||
set: false,
|
||||
is_local: !global.unwrap_or(false),
|
||||
}),
|
||||
false,
|
||||
!global.unwrap_or(false),
|
||||
origin,
|
||||
)),
|
||||
scale: None,
|
||||
rotate_angle_axis: None,
|
||||
translate: None,
|
||||
|
Reference in New Issue
Block a user