From be2f7fde67e27b910bb3e12246852269430ac467 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Tue, 9 Dec 2025 16:09:46 -0600 Subject: [PATCH 1/2] API work for Translate By Feature. Part of https://github.com/KittyCAD/modeling-app/issues/9097 --- modeling-cmds/openapi/api.json | 89 ++++++++++++++++++++++++++++++++-- modeling-cmds/src/shared.rs | 44 ++++++++++++++++- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/modeling-cmds/openapi/api.json b/modeling-cmds/openapi/api.json index 07ccc2cc..c6ac1074 100644 --- a/modeling-cmds/openapi/api.json +++ b/modeling-cmds/openapi/api.json @@ -7376,13 +7376,17 @@ "translate": { "description": "Translate the replica this far along each dimension. Defaults to zero vector (i.e. same position as the original).", "default": { - "x": 0.0, - "y": 0.0, - "z": 0.0 + "point3d": { + "point": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + } + } }, "allOf": [ { - "$ref": "#/components/schemas/Point3d" + "$ref": "#/components/schemas/TranslateBy" } ] } @@ -7464,6 +7468,83 @@ "set" ] }, + "TranslateBy": { + "description": "How to translate in space.", + "oneOf": [ + { + "description": "Translate this much in each dimension.", + "type": "object", + "properties": { + "point3d": { + "type": "object", + "properties": { + "point": { + "description": "Which vector to translate along.", + "allOf": [ + { + "$ref": "#/components/schemas/Point3d" + } + ] + } + }, + "required": [ + "point" + ] + } + }, + "required": [ + "point3d" + ], + "additionalProperties": false + }, + { + "description": "Translate along this edge or path segment.\n\nIf the edge is a circle, translates along the normal vector of this circle, going through the circle's center.\n\nIf the edge is linear, translates along that line's vector.", + "type": "object", + "properties": { + "edge": { + "type": "object", + "properties": { + "id": { + "description": "Which edge to translate along.", + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + } + }, + "required": [ + "edge" + ], + "additionalProperties": false + }, + { + "description": "Translate along this face or sketch.\n\nIf the sketch is circular, translate along the normal vector of the face/sketch, through its center.\n\nIf the face is circular (i.e. the end of a cone or cylinder), this works the same as translating along a circular sketch.", + "type": "object", + "properties": { + "face": { + "type": "object", + "properties": { + "id": { + "description": "Which face to translate along.", + "type": "string", + "format": "uuid" + } + }, + "required": [ + "id" + ] + } + }, + "required": [ + "face" + ], + "additionalProperties": false + } + ] + }, "UnitAngle": { "description": "The valid types of angle formats.", "oneOf": [ diff --git a/modeling-cmds/src/shared.rs b/modeling-cmds/src/shared.rs index f8fec200..099bca2c 100644 --- a/modeling-cmds/src/shared.rs +++ b/modeling-cmds/src/shared.rs @@ -83,6 +83,48 @@ impl Default for Rotation { } } +/// How to translate in space. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))] +#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))] +pub enum TranslateBy { + /// Translate this much in each dimension. + Point3d { + /// Which vector to translate along. + point: Point3d, + }, + /// Translate along this edge or path segment. + /// + /// If the edge is a circle, translates along the + /// normal vector of this circle, going through the circle's center. + /// + /// If the edge is linear, translates along that line's vector. + Edge { + /// Which edge to translate along. + id: Uuid, + }, + /// Translate along this face or sketch. + /// + /// If the sketch is circular, translate along + /// the normal vector of the face/sketch, through its center. + /// + /// If the face is circular (i.e. the end of a cone or cylinder), + /// this works the same as translating along a circular sketch. + Face { + /// Which face to translate along. + id: Uuid, + }, +} + +impl Default for TranslateBy { + fn default() -> Self { + Self::Point3d { + point: Default::default(), + } + } +} + /// Ways to transform each solid being replicated in a repeating pattern. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -92,7 +134,7 @@ pub struct Transform { /// Translate the replica this far along each dimension. /// Defaults to zero vector (i.e. same position as the original). #[serde(default)] - pub translate: Point3d, + pub translate: TranslateBy, /// Scale the replica's size along each axis. /// Defaults to (1, 1, 1) (i.e. the same size as the original). #[serde(default = "same_scale")] From 1d1ea06414d0d753344dcaced9720608d35e0bf9 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Tue, 9 Dec 2025 17:26:50 -0600 Subject: [PATCH 2/2] Explicitly call out when errors will happen --- modeling-cmds/src/shared.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modeling-cmds/src/shared.rs b/modeling-cmds/src/shared.rs index 099bca2c..2fa2d6c4 100644 --- a/modeling-cmds/src/shared.rs +++ b/modeling-cmds/src/shared.rs @@ -100,6 +100,8 @@ pub enum TranslateBy { /// normal vector of this circle, going through the circle's center. /// /// If the edge is linear, translates along that line's vector. + /// + /// If the edge is neither circular nor linear, the API will respond with an error. Edge { /// Which edge to translate along. id: Uuid, @@ -111,6 +113,8 @@ pub enum TranslateBy { /// /// If the face is circular (i.e. the end of a cone or cylinder), /// this works the same as translating along a circular sketch. + /// + /// If the face is not circular, the API will respond with an error. Face { /// Which face to translate along. id: Uuid,