Skip to content

Commit 4122c15

Browse files
authored
Allow rotation to use any point as its origin
Adds a new field `origin` to `TransformBy` allowing it to use any point as the origin. If this point isn't provided, falls back to the local or global origin, depending on the `is_local` field.
1 parent 622c0b7 commit 4122c15

File tree

1 file changed

+76
-15
lines changed

1 file changed

+76
-15
lines changed

modeling-cmds/src/shared.rs

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,8 +1021,60 @@ impl ExtrudedFaceInfo {
10211021

10221022
#[cfg(test)]
10231023
mod tests {
1024+
use schemars::schema_for;
1025+
10241026
use super::*;
10251027

1028+
#[test]
1029+
fn check_transformby_deprecated() {
1030+
let s = schema_for!(TransformBy<Point3d>);
1031+
let pretty = serde_json::to_string_pretty(&s).unwrap();
1032+
println!("{pretty}");
1033+
let tests: Vec<(OriginType, TransformBy<Point3d>)> = vec![
1034+
// get_origin should fall back to `is_local`, because `origin` is none.
1035+
(
1036+
OriginType::Local,
1037+
TransformBy {
1038+
property: Point3d::default(),
1039+
set: true,
1040+
#[allow(deprecated)] // still need to test deprecated code
1041+
is_local: true,
1042+
origin: None,
1043+
},
1044+
),
1045+
// get_origin should ignore `is_local`, because `origin` is given.
1046+
// test the case where origin is not custom
1047+
(
1048+
OriginType::Local,
1049+
TransformBy {
1050+
property: Point3d::default(),
1051+
set: true,
1052+
#[allow(deprecated)] // still need to test deprecated code
1053+
is_local: false,
1054+
origin: Some(OriginType::Local),
1055+
},
1056+
),
1057+
// get_origin should ignore `is_local`, because `origin` is given.
1058+
// test the case where origin is custom.
1059+
(
1060+
OriginType::Custom {
1061+
origin: Point3d::uniform(2.0),
1062+
},
1063+
TransformBy {
1064+
property: Point3d::default(),
1065+
set: true,
1066+
#[allow(deprecated)] // still need to test deprecated code
1067+
is_local: false,
1068+
origin: Some(OriginType::Custom{origin: Point3d::uniform(2.0)}),
1069+
},
1070+
),
1071+
];
1072+
for (expected, input) in tests {
1073+
let actual = input.get_origin();
1074+
assert_eq!(actual, expected);
1075+
}
1076+
}
1077+
10261078
#[test]
10271079
fn test_angle_comparison() {
10281080
let a = Angle::from_degrees(90.0);
@@ -1049,7 +1101,8 @@ mod tests {
10491101
}
10501102

10511103
/// How a property of an object should be transformed.
1052-
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
1104+
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
1105+
#[schemars(rename = "TransformByFor{T}")]
10531106
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
10541107
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
10551108
pub struct TransformBy<T> {
@@ -1062,24 +1115,32 @@ pub struct TransformBy<T> {
10621115
pub set: bool,
10631116
/// If true, the transform is applied in local space.
10641117
/// If false, the transform is applied in global space.
1118+
#[deprecated(note = "Use the `origin` field instead.")]
10651119
pub is_local: bool,
1120+
/// What to use as the origin for the transformation.
1121+
/// If not provided, will fall back to local or global origin, depending on
1122+
/// whatever the `is_local` field was set to.
1123+
#[serde(default)]
1124+
pub origin: Option<OriginType>,
10661125
}
10671126

1068-
impl<T: JsonSchema> JsonSchema for TransformBy<T> {
1069-
fn schema_name() -> String {
1070-
format!("TransformByFor{}", T::schema_name())
1071-
}
1072-
1073-
fn schema_id() -> std::borrow::Cow<'static, str> {
1074-
std::borrow::Cow::Owned(format!("{}::TransformBy<{}>", module_path!(), T::schema_id()))
1075-
}
1076-
1077-
fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1078-
SchemaObject {
1079-
instance_type: Some(schemars::schema::InstanceType::String.into()),
1080-
..Default::default()
1127+
impl<T> TransformBy<T> {
1128+
/// Get the origin of this transformation.
1129+
/// Reads from the `origin` field if it's set, otherwise
1130+
/// falls back to the `is_local` field.
1131+
pub fn get_origin(&self) -> OriginType {
1132+
if let Some(origin) = self.origin {
1133+
return origin;
1134+
}
1135+
#[expect(
1136+
deprecated,
1137+
reason = "Must fall back to the deprecated field if the API client isn't using the new field yet."
1138+
)]
1139+
if self.is_local {
1140+
OriginType::Local
1141+
} else {
1142+
OriginType::Global
10811143
}
1082-
.into()
10831144
}
10841145
}
10851146

0 commit comments

Comments
 (0)