Skip to main content

kittycad_modeling_cmds/
def_enum.rs

1use kittycad_modeling_cmds_macros::define_modeling_cmd_enum;
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4
5pub use self::each_cmd::*;
6use crate::{self as kittycad_modeling_cmds};
7
8define_modeling_cmd_enum! {
9    pub mod each_cmd {
10        use std::collections::HashSet;
11
12        use bon::Builder;
13        use crate::{self as kittycad_modeling_cmds};
14        use kittycad_modeling_cmds_macros::{ModelingCmdVariant};
15        use parse_display_derive::{Display, FromStr};
16        use schemars::JsonSchema;
17        use serde::{Deserialize, Serialize};
18        use uuid::Uuid;
19        use crate::shared::CameraViewState;
20        use crate::shared::MirrorAcross;
21
22        use crate::{
23            format::{OutputFormat2d, OutputFormat3d},
24            id::ModelingCmdId,
25            length_unit::LengthUnit,
26            shared::{
27                Angle,
28                RegionVersion,
29                BlendType,
30                BodyType,
31                EdgeCutVersion,
32                ComponentTransform,
33                RelativeTo,
34                CutType, CutTypeV2,
35                CutStrategy,
36                CameraMovement,
37                DirectionType,
38                EdgeSpecifier,
39                EntityReference,
40                ExtrudedFaceInfo, ExtrudeMethod,
41                AnnotationOptions, AnnotationType, CameraDragInteractionType, Color, DistanceType, EntityType,
42                PathComponentConstraintBound, PathComponentConstraintType, PathSegment, PerspectiveCameraParameters,
43                Point2d, Point3d, ExtrudeReference, SceneSelectionType, SceneToolType, SurfaceEdgeReference, Opposite,
44            },
45            units,
46        };
47
48        /// Mike says this usually looks nice.
49        fn default_animation_seconds() -> f64 {
50            0.4
51        }
52
53        fn mm() -> crate::units::UnitLength {
54            crate::units::UnitLength::Millimeters
55        }
56
57        /// Evaluates the position of a path in one shot (engine utility for kcl executor)
58        #[derive(
59            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
60        )]
61        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
62        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
63        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
64        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
65        pub struct EngineUtilEvaluatePath {
66            /// The path in json form (the serialized result of the kcl Sketch/Path object
67            pub path_json: String,
68
69            /// The evaluation parameter (path curve parameter in the normalized domain [0, 1])
70            pub t: f64,
71        }
72
73        /// Start a new path.
74        #[derive(
75            Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant,
76            Builder
77        )]
78        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
79        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
80        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
81        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
82        pub struct StartPath {}
83
84        /// Move the path's "pen".
85        /// If you're in sketch mode, these coordinates are in the local coordinate system,
86        /// not the world's coordinate system.
87        /// For example, say you're sketching on the plane {x: (1,0,0), y: (0,1,0), origin: (0, 0, 50)}.
88        /// In other words, the plane 50 units above the default XY plane. Then, moving the pen
89        /// to (1, 1, 0) with this command uses local coordinates. So, it would move the pen to
90        /// (1, 1, 50) in global coordinates.
91        #[derive(
92            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
93        )]
94        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
95        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
96        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
97        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
98        pub struct MovePathPen {
99            /// The ID of the command which created the path.
100            pub path: ModelingCmdId,
101            /// Where the path's pen should be.
102            pub to: Point3d<LengthUnit>,
103        }
104
105        /// Extend a path by adding a new segment which starts at the path's "pen".
106        /// If no "pen" location has been set before (via `MovePen`), then the pen is at the origin.
107        #[derive(
108            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
109        )]
110        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
111        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
112        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
113        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
114        pub struct ExtendPath {
115            /// The ID of the command which created the path.
116            pub path: ModelingCmdId,
117            /// Segment to append to the path.
118            /// This segment will implicitly begin at the current "pen" location.
119            pub segment: PathSegment,
120            /// Optional label to associate with the new path segment.
121            #[serde(default, skip_serializing_if = "Option::is_none")]
122            pub label: Option<String>,
123        }
124
125        /// Command for extruding a solid 2d.
126        #[derive(
127            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
128        )]
129        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
130        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
131        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
132        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
133        pub struct Extrude {
134            /// Which sketch to extrude.
135            /// Must be a closed 2D solid.
136            pub target: ModelingCmdId,
137            /// How far off the plane to extrude
138            pub distance: LengthUnit,
139            /// What direction to extrude in. If None, the engine will extrude in the direction normal of the target's plane.
140            #[serde(default, skip_serializing_if = "Option::is_none")]
141            pub direction: Option<DirectionType>,
142            /// What draft angle should be used in this extrusion?
143            /// Negative values indicate an outward draft,
144            /// while positive values indicate an inward draft
145            #[serde(default, skip_serializing_if = "Option::is_none")]
146            pub draft_angle: Option<Angle>,
147            /// Which IDs should the new faces have?
148            /// If this isn't given, the engine will generate IDs.
149            #[serde(default)]
150            pub faces: Option<ExtrudedFaceInfo>,
151            /// Should the extrusion also extrude in the opposite direction?
152            /// If so, this specifies its distance.
153            #[serde(default)]
154            #[builder(default)]
155            pub opposite: Opposite<LengthUnit>,
156            /// Should the extrusion create a new object or be part of the existing object.
157            #[builder(default)]
158            #[serde(default)]
159            pub extrude_method: ExtrudeMethod,
160            /// Only used if the extrusion is created from a face and extrude_method = Merge
161            /// If true, coplanar faces will be merged and seams will be hidden.
162            /// Otherwise, seams between the extrusion and original body will be shown.
163            #[serde(default, skip_serializing_if = "Option::is_none")]
164            pub merge_coplanar_faces: Option<bool>,
165
166            /// Should this extrude create a solid body or a surface?
167            #[serde(default)]
168            #[builder(default)]
169            pub body_type: BodyType,
170        }
171
172        /// Command for extruding a solid 2d to a reference geometry.
173        #[derive(
174            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
175        )]
176        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
177        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
178        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
179        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
180        pub struct ExtrudeToReference {
181            /// Which sketch to extrude.
182            /// Must be a closed 2D solid.
183            pub target: ModelingCmdId,
184            /// Reference to extrude to.
185            /// Extrusion occurs along the target's normal until it is as close to the reference as possible.
186            pub reference: ExtrudeReference,
187            /// Which IDs should the new faces have?
188            /// If this isn't given, the engine will generate IDs.
189            #[serde(default)]
190            pub faces: Option<ExtrudedFaceInfo>,
191            /// Should the extrusion create a new object or be part of the existing object.
192            #[serde(default)]
193            #[builder(default)]
194            pub extrude_method: ExtrudeMethod,
195            /// Should this extrude create a solid body or a surface?
196            #[serde(default)]
197            #[builder(default)]
198            pub body_type: BodyType,
199        }
200
201        fn default_twist_extrude_section_interval() -> Angle {
202            Angle::from_degrees(15.0)
203        }
204
205        /// Command for twist extruding a solid 2d.
206        #[derive(
207            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
208        )]
209        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
210        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
211        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
212        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
213        pub struct TwistExtrude {
214            /// Which sketch to extrude.
215            /// Must be a closed 2D solid.
216            pub target: ModelingCmdId,
217            /// How far off the plane to extrude
218            pub distance: LengthUnit,
219            /// Which IDs should the new faces have?
220            /// If this isn't given, the engine will generate IDs.
221            #[serde(default)]
222            pub faces: Option<ExtrudedFaceInfo>,
223            /// Center to twist about (relative to plane's origin)
224            /// Defaults to `[0, 0]` i.e. the plane's origin
225            #[serde(default)]
226            #[builder(default)]
227            pub center_2d: Point2d<f64>,
228            /// Total rotation of the section
229            pub total_rotation_angle: Angle,
230            /// Angle step interval (converted to whole number degrees and bounded between 4° and 90°)
231            #[serde(default = "default_twist_extrude_section_interval")]
232            #[builder(default = default_twist_extrude_section_interval())]
233            pub angle_step_size: Angle,
234            /// The twisted surface loft tolerance
235            pub tolerance: LengthUnit,
236            /// Should this extrude create a solid body or a surface?
237            #[serde(default)]
238            #[builder(default)]
239            pub body_type: BodyType,
240        }
241
242        /// Extrude the object along a path.
243        #[derive(
244            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder
245        )]
246        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
247        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
248        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
249        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
250        pub struct Sweep {
251            /// Which sketch to sweep.
252            /// Must be a closed 2D solid.
253            pub target: ModelingCmdId,
254            /// Path along which to sweep.
255            pub trajectory: ModelingCmdId,
256            /// If true, the sweep will be broken up into sub-sweeps (extrusions, revolves, sweeps) based on the trajectory path components.
257            pub sectional: bool,
258            /// The maximum acceptable surface gap computed between the revolution surface joints. Must be positive (i.e. greater than zero).
259            pub tolerance: LengthUnit,
260            /// Should this sweep create a solid body or a surface?
261            #[serde(default)]
262            #[builder(default)]
263            pub body_type: BodyType,
264            /// What is this sweep relative to?
265            /// Deprecated; please use `translate_profile_to_path` and `orient_profile_perpendicular` instead.
266            #[serde(default)]
267            pub relative_to: Option<RelativeTo>,
268            /// What version of the sweeping algorithm to use. If None, or zero, the engine's
269            /// default algorithm will be used
270            #[serde(default, skip_serializing_if = "Option::is_none")]
271            pub version: Option<u8>,
272            /// If true, the profile being swept will be moved to the path being swept along,
273            /// before the sweep starts.
274            /// If false, the profile stays where it is, and the sweep starts from there.
275            /// Defaults to false.
276            #[serde(default, skip_serializing_if = "Option::is_none")]
277            pub translate_profile_to_path: Option<bool>,
278            /// If true, before the sweep starts, the profile will be re-oriented
279            /// so that it is perpendicular to the path being swept along.
280            /// If false, the profile is left in its current orientation.
281            /// Defaults to false.
282            #[serde(default, skip_serializing_if = "Option::is_none")]
283            pub orient_profile_perpendicular: Option<bool>,
284        }
285
286        /// Command for revolving a solid 2d.
287        #[derive(
288            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
289        )]
290        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
291        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
292        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
293        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
294        pub struct Revolve {
295            /// Which sketch to revolve.
296            /// Must be a closed 2D solid.
297            pub target: ModelingCmdId,
298            /// The origin of the extrusion axis
299            pub origin: Point3d<LengthUnit>,
300            /// The axis of the extrusion (taken from the origin)
301            pub axis: Point3d<f64>,
302            /// If true, the axis is interpreted within the 2D space of the solid 2D's plane
303            pub axis_is_2d: bool,
304            /// The signed angle of revolution (in degrees, must be <= 360 in either direction)
305            pub angle: Angle,
306            /// The maximum acceptable surface gap computed between the revolution surface joints. Must be positive (i.e. greater than zero).
307            pub tolerance: LengthUnit,
308            /// Should the revolution also revolve in the opposite direction along the given axis?
309            /// If so, this specifies its angle.
310            #[serde(default)]
311            #[builder(default)]
312            pub opposite: Opposite<Angle>,
313            /// Should this extrude create a solid body or a surface?
314            #[serde(default)]
315            #[builder(default)]
316            pub body_type: BodyType,
317        }
318
319        /// Command for shelling a solid3d face
320        #[derive(
321            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
322        )]
323        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
324        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
325        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
326        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
327        pub struct Solid3dShellFace {
328            /// Which Solid3D is being shelled.
329            pub object_id: Uuid,
330            /// Which faces to remove, leaving only the shell.
331            pub face_ids: Vec<Uuid>,
332            /// How thick the shell should be.
333            /// Smaller values mean a thinner shell.
334            pub shell_thickness: LengthUnit,
335            /// If true, the Solid3D is made hollow instead of removing the selected faces
336            #[serde(default)]
337            #[builder(default)]
338            pub hollow: bool,
339        }
340
341        /// Command for joining a Surface (non-manifold) body back to a Solid.
342        /// All of the surfaces should already be contained within the body mated topologically.
343        /// This operation should be the final step after a sequence of Solid modeling commands such as
344        /// BooleanImprint, EntityDeleteChildren, Solid3dFlipFace
345        /// If successful, the new body type will become "Solid".
346        #[derive(
347            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
348        )]
349        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
350        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
351        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
352        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
353        pub struct Solid3dJoin {
354            /// Which Solid3D is being joined.
355            pub object_id: Uuid,
356        }
357
358        /// Command for joining multiple Surfaces (non-manifold) to a Solid.
359        #[derive(
360            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
361        )]
362        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
363        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
364        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
365        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
366        pub struct Solid3dMultiJoin {
367            /// Which bodies are being joined.
368            pub object_ids: Vec<Uuid>,
369            /// The maximum acceptable surface gap computed between the joints. Must be positive (i.e. greater than zero).
370            pub tolerance: LengthUnit,
371        }
372
373
374        /// Command for creating a blend between the edge of two given surfaces
375        #[derive(
376            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
377        )]
378        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
379        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
380        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
381        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
382        pub struct SurfaceBlend {
383            /// The two surfaces that the blend will span between
384            #[schemars(length(min = 2, max = 2))]
385            pub surfaces: Vec<SurfaceEdgeReference>,
386            /// The type of blend to use.
387            #[serde(default)]
388            #[builder(default)]
389            pub blend_type: BlendType,
390        }
391
392        /// What is the UUID of this body's n-th edge?
393        #[derive(
394            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
395        )]
396        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
397        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
398        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
399        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
400        pub struct Solid3dGetEdgeUuid {
401            /// The Solid3D parent who owns the edge
402            pub object_id: Uuid,
403
404            /// The primitive index of the edge being queried.
405            pub edge_index: u32,
406        }
407
408        /// What is the UUID of this body's n-th face?
409        #[derive(
410            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
411        )]
412        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
413        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
414        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
415        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
416        pub struct Solid3dGetFaceUuid {
417            /// The Solid3D parent who owns the face
418            pub object_id: Uuid,
419
420            /// The primitive index of the face being queried.
421            pub face_index: u32,
422        }
423
424        /// Retrieves the body type.
425        #[derive(
426            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
427        )]
428        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
429        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
430        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
431        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
432        pub struct Solid3dGetBodyType {
433            /// The Solid3D whose body type is being queried.
434            pub object_id: Uuid,
435        }
436
437        /// Command for revolving a solid 2d about a brep edge
438        #[derive(
439            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
440        )]
441        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
442        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
443        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
444        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
445        pub struct RevolveAboutEdge {
446            /// Which sketch to revolve.
447            /// Must be a closed 2D solid.
448            pub target: ModelingCmdId,
449            /// The edge to use as the axis of revolution, must be linear and lie in the plane of the solid
450            #[serde(default, skip_serializing_if = "Option::is_none")]
451            pub edge_id: Option<Uuid>,
452            /// Edge reference to use as the axis of revolution (new API).
453            /// If both `edge_id` and `edge_reference` are provided, `edge_reference` takes precedence.
454            #[serde(default, skip_serializing_if = "Option::is_none")]
455            pub edge_reference: Option<EdgeSpecifier>,
456            /// The signed angle of revolution (in degrees, must be <= 360 in either direction)
457            pub angle: Angle,
458            /// The maximum acceptable surface gap computed between the revolution surface joints. Must be positive (i.e. greater than zero).
459            pub tolerance: LengthUnit,
460            /// Should the revolution also revolve in the opposite direction along the given axis?
461            /// If so, this specifies its angle.
462            #[serde(default)]
463            #[builder(default)]
464            pub opposite: Opposite<Angle>,
465            /// Should this extrude create a solid body or a surface?
466            #[serde(default)]
467            #[builder(default)]
468            pub body_type: BodyType,
469        }
470
471        /// Command for lofting sections to create a solid
472        #[derive(
473            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
474        )]
475        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
476        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
477        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
478        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
479        pub struct Loft {
480            /// The closed section curves to create a lofted solid from.
481            /// Currently, these must be Solid2Ds
482            pub section_ids: Vec<Uuid>,
483            /// Degree of the interpolation. Must be greater than zero.
484            /// For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction.
485            pub v_degree: std::num::NonZeroU32,
486            /// Attempt to approximate rational curves (such as arcs) using a bezier.
487            /// This will remove banding around interpolations between arcs and non-arcs.  It may produce errors in other scenarios
488            /// Over time, this field won't be necessary.
489            pub bez_approximate_rational: bool,
490            /// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
491            pub base_curve_index: Option<u32>,
492            /// Tolerance
493            pub tolerance: LengthUnit,
494            /// Should this loft create a solid body or a surface?
495            #[serde(default)]
496            #[builder(default)]
497            pub body_type: BodyType,
498        }
499
500
501        /// Closes a path, converting it to a 2D solid.
502        #[derive(
503            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
504        )]
505        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
506        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
507        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
508        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
509        pub struct ClosePath {
510            /// Which path to close.
511            pub path_id: Uuid,
512        }
513
514        /// Camera drag started.
515        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
516        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
517        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
518        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
519        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
520        pub struct CameraDragStart {
521            /// The type of camera drag interaction.
522            pub interaction: CameraDragInteractionType,
523            /// The initial mouse position.
524            pub window: Point2d,
525        }
526
527        /// Camera drag continued.
528        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
529        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
530        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
531        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
532        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
533        pub struct CameraDragMove {
534            /// The type of camera drag interaction.
535            pub interaction: CameraDragInteractionType,
536            /// The current mouse position.
537            pub window: Point2d,
538            /// Logical timestamp. The client should increment this
539            /// with every event in the current mouse drag. That way, if the
540            /// events are being sent over an unordered channel, the API
541            /// can ignore the older events.
542            pub sequence: Option<u32>,
543        }
544
545        /// Camera drag ended
546        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
547        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
548        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
549        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
550        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
551        pub struct CameraDragEnd {
552            /// The type of camera drag interaction.
553            pub interaction: CameraDragInteractionType,
554            /// The final mouse position.
555            pub window: Point2d,
556        }
557
558        /// Gets the default camera's camera settings
559        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
560        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
561        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
562        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
563        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
564        pub struct DefaultCameraGetSettings {}
565
566        /// Gets the default camera's view state
567        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
568        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
569        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
570        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
571        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
572        pub struct DefaultCameraGetView {}
573
574        /// Sets the default camera's view state
575        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
576        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
577        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
578        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
579        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
580        pub struct DefaultCameraSetView {
581            /// Camera view state
582            pub view: CameraViewState,
583        }
584
585        /// Change what the default camera is looking at.
586        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
587        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
588        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
589        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
590        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
591        pub struct DefaultCameraLookAt {
592            /// Where the camera is positioned
593            pub vantage: Point3d,
594            /// What the camera is looking at. Center of the camera's field of vision
595            pub center: Point3d,
596            /// Which way is "up", from the camera's point of view.
597            pub up: Point3d,
598            /// Logical timestamp. The client should increment this
599            /// with every event in the current mouse drag. That way, if the
600            /// events are being sent over an unordered channel, the API
601            /// can ignore the older events.
602            pub sequence: Option<u32>,
603        }
604
605        /// Change what the default camera is looking at.
606        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
607        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
608        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
609        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
610        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
611        pub struct DefaultCameraPerspectiveSettings {
612            /// Where the camera is positioned
613            pub vantage: Point3d,
614            /// What the camera is looking at. Center of the camera's field of vision
615            pub center: Point3d,
616            /// Which way is "up", from the camera's point of view.
617            pub up: Point3d,
618            /// The field of view angle in the y direction, in degrees.
619            pub fov_y: Option<f32>,
620            /// The distance to the near clipping plane.
621            pub z_near: Option<f32>,
622            /// The distance to the far clipping plane.
623            pub z_far: Option<f32>,
624            /// Logical timestamp. The client should increment this
625            /// with every event in the current mouse drag. That way, if the
626            /// events are being sent over an unordered channel, the API
627            /// can ignore the older events.
628            pub sequence: Option<u32>,
629        }
630
631        /// Adjust zoom of the default camera.
632        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
633        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
634        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
635        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
636        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
637        pub struct DefaultCameraZoom {
638            /// Move the camera forward along the vector it's looking at,
639            /// by this magnitudedefaultCameraZoom.
640            /// Basically, how much should the camera move forward by.
641            pub magnitude: f32,
642        }
643
644        /// Export a sketch to a file.
645        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
646        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
647        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
648        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
649        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
650        pub struct Export2d {
651            /// IDs of the entities to be exported.
652            pub entity_ids: Vec<Uuid>,
653            /// The file format to export to.
654            pub format: OutputFormat2d,
655        }
656
657        /// Export the scene to a file.
658        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
659        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
660        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
661        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
662        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
663        pub struct Export3d {
664            /// IDs of the entities to be exported. If this is empty, then all entities are exported.
665            #[builder(default)]
666            pub entity_ids: Vec<Uuid>,
667            /// The file format to export to.
668            pub format: OutputFormat3d,
669        }
670
671        /// Export the scene to a file.
672        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
673        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
674        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
675        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
676        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
677        pub struct Export {
678            /// IDs of the entities to be exported. If this is empty, then all entities are exported.
679            #[builder(default)]
680            pub entity_ids: Vec<Uuid>,
681            /// The file format to export to.
682            pub format: OutputFormat3d,
683        }
684
685        /// What is this entity's parent?
686        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
687        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
688        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
689        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
690        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
691        pub struct EntityGetParentId {
692            /// ID of the entity being queried.
693            pub entity_id: Uuid,
694        }
695
696        /// How many children does the entity have?
697        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
698        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
699        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
700        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
701        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
702        pub struct EntityGetNumChildren {
703            /// ID of the entity being queried.
704            pub entity_id: Uuid,
705        }
706
707        /// What is the UUID of this entity's n-th child?
708        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
709        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
710        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
711        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
712        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
713        pub struct EntityGetChildUuid {
714            /// ID of the entity being queried.
715            pub entity_id: Uuid,
716            /// Index into the entity's list of children.
717            pub child_index: u32,
718        }
719
720        /// What is this entity's child index within its parent
721        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
722        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
723        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
724        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
725        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
726        pub struct EntityGetIndex {
727            /// ID of the entity being queried.
728            pub entity_id: Uuid,
729        }
730
731        /// What is this edge or face entity's primitive index within its parent body's edges or faces array respectively
732        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
733        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
734        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
735        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
736        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
737        pub struct EntityGetPrimitiveIndex {
738            /// ID of the entity being queried.
739            pub entity_id: Uuid,
740        }
741
742        /// Attempts to delete children entity from an entity.
743        /// Note that this API may change the body type of certain entities from Solid to Surface.
744        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
745        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
746        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
747        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
748        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
749        pub struct EntityDeleteChildren {
750            /// ID of the entity being modified
751            pub entity_id: Uuid,
752            /// ID of the entity's child being deleted
753            pub child_entity_ids: HashSet<Uuid>,
754        }
755
756        /// What are all UUIDs of this entity's children?
757        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
758        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
759        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
760        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
761        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
762        pub struct EntityGetAllChildUuids {
763            /// ID of the entity being queried.
764            pub entity_id: Uuid,
765        }
766
767        /// What are all UUIDs of all the paths sketched on top of this entity?
768        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
769        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
770        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
771        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
772        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
773        pub struct EntityGetSketchPaths {
774            /// ID of the entity being queried.
775            pub entity_id: Uuid,
776        }
777
778        /// What is the distance between these two entities?
779        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
780        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
781        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
782        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
783        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
784        pub struct EntityGetDistance {
785            /// ID of the first entity being queried.
786            pub entity_id1: Uuid,
787            /// ID of the second entity being queried.
788            pub entity_id2: Uuid,
789            /// Type of distance to be measured.
790            pub distance_type: DistanceType,
791        }
792
793        /// What is the length of this edge?
794        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
795        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
796        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
797        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
798        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
799        pub struct EdgeGetLength {
800            /// ID of the edge being queried.
801            pub edge_id: Uuid,
802        }
803
804        /// Create a pattern using this entity by specifying the transform for each desired repetition.
805        /// Transformations are performed in the following order (first applied to last applied): scale, rotate, translate.
806        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
807        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
808        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
809        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
810        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
811        pub struct EntityClone {
812            /// ID of the entity being cloned.
813            pub entity_id: Uuid,
814        }
815
816        /// Create a pattern using this entity by specifying the transform for each desired repetition.
817        /// Transformations are performed in the following order (first applied to last applied): scale, rotate, translate.
818        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
819        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
820        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
821        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
822        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
823        pub struct EntityLinearPatternTransform {
824            /// ID of the entity being copied.
825            pub entity_id: Uuid,
826            /// How to transform each repeated solid.
827            /// The 0th transform will create the first copy of the entity.
828            /// The total number of (optional) repetitions equals the size of this list.
829            #[serde(default)]
830            #[builder(default)]
831            pub transform: Vec<crate::shared::Transform>,
832            /// Alternatively, you could set this key instead.
833            /// If you want to use multiple transforms per item.
834            /// If this is non-empty then the `transform` key must be empty, and vice-versa.
835            #[serde(default)]
836            #[builder(default)]
837            pub transforms: Vec<Vec<crate::shared::Transform>>,
838        }
839
840        /// Create a linear pattern using this entity.
841        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
842        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
843        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
844        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
845        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
846        pub struct EntityLinearPattern {
847            /// ID of the entity being copied.
848            pub entity_id: Uuid,
849            /// Axis along which to make the copies.
850            /// For Solid2d patterns, the z component is ignored.
851            pub axis: Point3d<f64>,
852            /// Number of repetitions to make.
853            pub num_repetitions: u32,
854            /// Spacing between repetitions.
855            pub spacing: LengthUnit,
856        }
857        /// Create a circular pattern using this entity.
858        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
859        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
860        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
861        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
862        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
863        pub struct EntityCircularPattern {
864            /// ID of the entity being copied.
865            pub entity_id: Uuid,
866            /// Axis around which to make the copies.
867            /// For Solid2d patterns, this is ignored.
868            pub axis: Point3d<f64>,
869            /// Point around which to make the copies.
870            /// For Solid2d patterns, the z component is ignored.
871            pub center: Point3d<LengthUnit>,
872            /// Number of repetitions to make.
873            pub num_repetitions: u32,
874            /// Arc angle (in degrees) to place repetitions along.
875            pub arc_degrees: f64,
876            /// Whether or not to rotate the objects as they are copied.
877            pub rotate_duplicates: bool,
878        }
879
880        /// Create a helix using the input cylinder and other specified parameters.
881        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
882        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
883        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
884        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
885        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
886        pub struct EntityMakeHelix {
887            /// ID of the cylinder.
888            pub cylinder_id: Uuid,
889            /// Number of revolutions.
890            pub revolutions: f64,
891            /// Start angle.
892            #[serde(default)]
893            #[builder(default)]
894            pub start_angle: Angle,
895            /// Is the helix rotation clockwise?
896            pub is_clockwise: bool,
897            /// Length of the helix. If None, the length of the cylinder will be used instead.
898            pub length: Option<LengthUnit>,
899        }
900
901        /// Create a helix using the specified parameters.
902        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
903        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
904        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
905        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
906        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
907        pub struct EntityMakeHelixFromParams {
908            /// Radius of the helix.
909            pub radius: LengthUnit,
910            /// Length of the helix.
911            pub length: LengthUnit,
912            /// Number of revolutions.
913            pub revolutions: f64,
914            /// Start angle.
915            #[serde(default)]
916            #[builder(default)]
917            pub start_angle: Angle,
918            /// Is the helix rotation clockwise?
919            pub is_clockwise: bool,
920            /// Center of the helix at the base of the helix.
921            pub center: Point3d<LengthUnit>,
922            /// Axis of the helix. The helix will be created around and in the direction of this axis.
923            pub axis: Point3d<f64>,
924        }
925
926        /// Create a helix using the specified parameters.
927        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
928        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
929        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
930        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
931        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
932        pub struct EntityMakeHelixFromEdge {
933            /// Radius of the helix.
934            pub radius: LengthUnit,
935            /// Length of the helix. If None, the length of the edge will be used instead.
936            pub length: Option<LengthUnit>,
937            /// Number of revolutions.
938            pub revolutions: f64,
939            /// Start angle.
940            #[serde(default)]
941            #[builder(default)]
942            pub start_angle: Angle,
943            /// Is the helix rotation clockwise?
944            pub is_clockwise: bool,
945            /// Edge ID about which to make the helix (legacy API, for backwards compatibility).
946            /// If both `edge_id` and `edge_reference` are provided, `edge_reference` takes precedence.
947            #[serde(default, skip_serializing_if = "Option::is_none")]
948            pub edge_id: Option<Uuid>,
949            /// Edge reference about which to make the helix (new API).
950            /// If both `edge_id` and `edge_reference` are provided, `edge_reference` takes precedence.
951            #[serde(default, skip_serializing_if = "Option::is_none")]
952            pub edge_reference: Option<EdgeSpecifier>,
953        }
954
955        /// Mirror the input entities over the specified axis, edge, or plane.
956        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
957        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
958        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
959        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
960        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
961        pub struct EntityMirrorAcross {
962            /// ID of the mirror entities.
963            pub ids: Vec<Uuid>,
964            /// What to mirror across
965            pub across: MirrorAcross,
966        }
967
968
969        /// Mirror the input entities over the specified axis.
970        /// Deprecated; please use `EntityMirrorAcross`
971        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
972        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
973        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
974        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
975        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
976        pub struct EntityMirror {
977            /// ID of the mirror entities.
978            pub ids: Vec<Uuid>,
979            /// Axis to use as mirror.
980            pub axis: Point3d<f64>,
981            /// Point through which the mirror axis passes.
982            pub point: Point3d<LengthUnit>,
983        }
984
985        /// Mirror the input entities over the specified edge.
986        /// Deprecated; please use `EntityMirrorAcross`
987        #[derive(
988            Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder
989        )]
990        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
991        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
992        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
993        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
994        pub struct EntityMirrorAcrossEdge {
995            /// ID of the mirror entities.
996            pub ids: Vec<Uuid>,
997            /// The edge to use as the mirror axis (legacy API). Must be linear and lie in the plane of the solid.
998            /// If both `edge_id` and `edge_reference` are provided, `edge_reference` takes precedence.
999            #[serde(default, skip_serializing_if = "Option::is_none")]
1000            pub edge_id: Option<Uuid>,
1001            /// Edge reference to use as the mirror axis (new API).
1002            /// If both `edge_id` and `edge_reference` are provided, `edge_reference` takes precedence.
1003            #[serde(default, skip_serializing_if = "Option::is_none")]
1004            pub edge_reference: Option<EdgeSpecifier>,
1005        }
1006
1007        /// Modifies the selection by simulating a "mouse click" at the given x,y window coordinate
1008        /// Returns ID of whatever was selected.
1009        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1010        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1011        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1012        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1013        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1014        pub struct SelectWithPoint {
1015            /// Where in the window was selected
1016            pub selected_at_window: Point2d,
1017            /// What entity was selected?
1018            pub selection_type: SceneSelectionType,
1019        }
1020
1021        /// Query the type of entity that was selected. E.g. if a face is selected the face id is
1022        /// returned, if an edge/vertex is selected then the face ids that uniquely define the edge/vertex are
1023        /// returned (typically two).
1024        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant)]
1025        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1026        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1027        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1028        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1029        pub struct QueryEntityTypeWithPoint {
1030            /// Where in the window was selected
1031            pub selected_at_window: Point2d,
1032            /// What entity was selected?
1033            pub selection_type: SceneSelectionType,
1034        }
1035
1036        /// Query the type of entity given its id. E.g. if a face is selected the face id is
1037        /// returned, if an edge/vertex is selected then the face ids that uniquely define the edge/vertex are
1038        /// returned (typically two).
1039        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant)]
1040        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1041        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1042        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1043        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1044        pub struct QueryEntityType {
1045            /// The entity id to query
1046            pub entity_id: Uuid,
1047        }
1048
1049        /// Adds one or more entities (by UUID) to the selection.
1050        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1051        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1052        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1053        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1054        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1055        pub struct SelectAdd {
1056            /// Which entities to select
1057            pub entities: Vec<Uuid>,
1058        }
1059
1060        /// Removes one or more entities (by UUID) from the selection.
1061        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1062        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1063        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1064        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1065        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1066        pub struct SelectRemove {
1067            /// Which entities to unselect
1068            pub entities: Vec<Uuid>,
1069        }
1070
1071        /// Removes all of the Objects in the scene
1072        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1073        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1074        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1075        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1076        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1077        pub struct SceneClearAll {}
1078
1079        /// Replaces current selection with these entities (by UUID).
1080        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1081        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1082        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1083        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1084        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1085        pub struct SelectReplace {
1086            /// Which entities to select
1087            pub entities: Vec<Uuid>,
1088        }
1089
1090        /// Changes the current highlighted entity to whichever one is at the given window coordinate.
1091        /// If there's no entity at this location, clears the highlight.
1092        #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1093        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1094        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1095        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1096        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1097        pub struct HighlightSetEntity {
1098            /// Coordinates of the window being clicked
1099            pub selected_at_window: Point2d,
1100            /// Logical timestamp. The client should increment this
1101            /// with every event in the current mouse drag. That way, if the
1102            /// events are being sent over an unordered channel, the API
1103            /// can ignore the older events.
1104            pub sequence: Option<u32>,
1105        }
1106
1107        /// Changes the current highlighted entity to these entities.
1108        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1109        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1110        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1111        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1112        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1113        pub struct HighlightSetEntities {
1114            /// Highlight these entities.
1115            pub entities: Vec<Uuid>,
1116        }
1117
1118        /// Create a new annotation
1119        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1120        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1121        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1122        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1123        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1124        pub struct NewAnnotation {
1125            /// What should the annotation contain?
1126            pub options: AnnotationOptions,
1127            /// If true, any existing drawables within the obj will be replaced (the object will be reset)
1128            pub clobber: bool,
1129            /// What type of annotation to create.
1130            pub annotation_type: AnnotationType,
1131        }
1132
1133        /// Update an annotation
1134        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1135        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1136        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1137        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1138        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1139        pub struct UpdateAnnotation {
1140            /// Which annotation to update
1141            pub annotation_id: Uuid,
1142            /// If any of these fields are set, they will overwrite the previous options for the
1143            /// annotation.
1144            pub options: AnnotationOptions,
1145        }
1146
1147        /// Changes visibility of scene-wide edge lines on brep solids
1148        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1149        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1150        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1151        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1152        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1153        pub struct EdgeLinesVisible {
1154            /// Whether or not the edge lines should be hidden.
1155            pub hidden: bool,
1156        }
1157
1158        /// Hide or show an object
1159        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1160        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1161        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1162        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1163        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1164        pub struct ObjectVisible {
1165            /// Which object to change
1166            pub object_id: Uuid,
1167            /// Whether or not the object should be hidden.
1168            pub hidden: bool,
1169        }
1170
1171        /// Bring an object to the front of the scene
1172        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1173        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1174        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1175        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1176        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1177        pub struct ObjectBringToFront {
1178            /// Which object to change
1179            pub object_id: Uuid,
1180        }
1181
1182        /// Set the material properties of an object
1183        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1184        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1185        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1186        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1187        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1188        pub struct ObjectSetMaterialParamsPbr {
1189            /// Which object to change
1190            pub object_id: Uuid,
1191            /// Color of the new material
1192            pub color: Color,
1193            /// Metalness of the new material
1194            pub metalness: f32,
1195            /// Roughness of the new material
1196            pub roughness: f32,
1197            /// Ambient Occlusion of the new material
1198            pub ambient_occlusion: f32,
1199            /// Color of the backface
1200            #[serde(default, skip_serializing_if = "Option::is_none")]
1201            pub backface_color: Option<Color>,
1202        }
1203
1204        /// Set the name of an object
1205        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1206        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1207        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1208        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1209        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1210        pub struct ObjectSetName {
1211            /// Which object to change
1212            pub object_id: Uuid,
1213            /// Name of the object. Using a zero-length name unsets the name.
1214            #[serde(default, skip_serializing_if = "String::is_empty")]
1215            pub name: String,
1216        }
1217
1218        /// What type of entity is this?
1219        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1220        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1221        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1222        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1223        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1224        pub struct GetEntityType {
1225            /// ID of the entity being queried.
1226            pub entity_id: Uuid,
1227        }
1228
1229        /// Gets all faces which use the given edge.
1230        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1231        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1232        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1233        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1234        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1235        pub struct Solid3dGetAllEdgeFaces {
1236            /// Which object is being queried.
1237            pub object_id: Uuid,
1238            /// Which edge you want the faces of.
1239            pub edge_id: Uuid,
1240        }
1241
1242        /// Flips (reverses) a brep that is "inside-out".
1243        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1244        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1245        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1246        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1247        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1248        pub struct Solid3dFlip {
1249            /// Which object is being flipped.
1250            pub object_id: Uuid,
1251        }
1252
1253        /// Flips (reverses) a face.  If the solid3d body type is "Solid",
1254        /// then body type will become non-manifold ("Surface").
1255        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1256        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1257        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1258        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1259        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1260        pub struct Solid3dFlipFace {
1261            /// Which object is being queried.
1262            pub object_id: Uuid,
1263            /// Which face you want to flip.
1264            pub face_id: Uuid,
1265        }
1266
1267        /// Add a hole to a Solid2d object before extruding it.
1268        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1269        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1270        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1271        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1272        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1273        pub struct Solid2dAddHole {
1274            /// Which object to add the hole to.
1275            pub object_id: Uuid,
1276            /// The id of the path to use as the inner profile (hole).
1277            pub hole_id: Uuid,
1278        }
1279
1280        /// Gets all edges which are opposite the given edge, across all possible faces.
1281        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1282        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1283        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1284        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1285        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1286        pub struct Solid3dGetAllOppositeEdges {
1287            /// Which object is being queried.
1288            pub object_id: Uuid,
1289            /// Which edge you want the opposites of.
1290            pub edge_id: Uuid,
1291            /// If given, only faces parallel to this vector will be considered.
1292            pub along_vector: Option<Point3d<f64>>,
1293        }
1294
1295        /// Gets the edge opposite the given edge, along the given face.
1296        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1297        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1298        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1299        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1300        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1301        pub struct Solid3dGetOppositeEdge {
1302            /// Which object is being queried.
1303            pub object_id: Uuid,
1304            /// Which edge you want the opposite of.
1305            pub edge_id: Uuid,
1306            /// Which face is used to figure out the opposite edge?
1307            pub face_id: Uuid,
1308        }
1309
1310        /// Gets the next adjacent edge for the given edge, along the given face.
1311        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1312        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1313        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1314        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1315        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1316        pub struct Solid3dGetNextAdjacentEdge {
1317            /// Which object is being queried.
1318            pub object_id: Uuid,
1319            /// Which edge you want the opposite of.
1320            pub edge_id: Uuid,
1321            /// Which face is used to figure out the opposite edge?
1322            pub face_id: Uuid,
1323        }
1324
1325        /// Gets the previous adjacent edge for the given edge, along the given face.
1326        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1327        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1328        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1329        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1330        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1331        pub struct Solid3dGetPrevAdjacentEdge {
1332            /// Which object is being queried.
1333            pub object_id: Uuid,
1334            /// Which edge you want the opposite of.
1335            pub edge_id: Uuid,
1336            /// Which face is used to figure out the opposite edge?
1337            pub face_id: Uuid,
1338        }
1339
1340        /// Gets the shared edge between these two faces if it exists
1341        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1342        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1343        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1344        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1345        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1346        pub struct Solid3dGetCommonEdge {
1347            /// Which object is being queried.
1348            pub object_id: Uuid,
1349            /// The faces being queried
1350            pub face_ids: [Uuid; 2]
1351        }
1352
1353        /// Fillets the given edge with the specified radius.
1354        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1355        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1356        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1357        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1358        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1359        pub struct Solid3dFilletEdge {
1360            /// Which object is being filletted.
1361            pub object_id: Uuid,
1362            /// Which edge you want to fillet.
1363            #[serde(default)]
1364            pub edge_id: Option<Uuid>,
1365            /// Which edges you want to fillet.
1366            #[serde(default)]
1367            #[builder(default)]
1368            pub edge_ids: Vec<Uuid>,
1369            /// A struct containing the information required to reference an edge.
1370            #[serde(default, skip_serializing_if = "Vec::is_empty")]
1371            #[builder(default)]
1372            pub edges_references: Vec<EdgeSpecifier>,
1373            /// The radius of the fillet. Measured in length (using the same units that the current sketch uses). Must be positive (i.e. greater than zero).
1374            pub radius: LengthUnit,
1375            /// The maximum acceptable surface gap computed between the filleted surfaces. Must be positive (i.e. greater than zero).
1376            pub tolerance: LengthUnit,
1377            /// How to apply the cut.
1378            #[serde(default)]
1379            #[builder(default)]
1380            pub cut_type: CutType,
1381            /// Which cutting algorithm to use.
1382            #[serde(default)]
1383            #[builder(default)]
1384            pub strategy: CutStrategy,
1385            /// What IDs should the resulting faces have?
1386            /// If you've only passed one edge ID, its ID will
1387            /// be the command ID used to send this command, and this
1388            /// field should be empty.
1389            /// If you've passed `n` IDs (to fillet `n` edges), then
1390            /// this should be length `n-1`, and the first edge will use
1391            /// the command ID used to send this command.
1392            #[serde(default)]
1393            #[builder(default)]
1394            pub extra_face_ids: Vec<Uuid>,
1395            /// If true, use the legacy CSG algorithm.
1396            #[serde(default, skip_serializing_if = "super::is_false")]
1397            #[builder(default)]
1398            pub use_legacy: bool,
1399            /// Which version of the edge cut algorithm to use.
1400            #[serde(default, skip_serializing_if = "EdgeCutVersion::is_default")]
1401            #[builder(default)]
1402            pub version: EdgeCutVersion,
1403        }
1404
1405        /// Cut the list of edge references with the given cut parameters
1406        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1407        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1408        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1409        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1410        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1411        pub struct Solid3dCutEdgeReferences {
1412            /// Which object is being cut.
1413            pub object_id: Uuid,
1414            /// A struct containing the information required to reference an edge.
1415            #[serde(default)]
1416            #[builder(default)]
1417            pub edges_references: Vec<EdgeSpecifier>,
1418            /// The cut type and information required to perform the cut.
1419            pub cut_type: CutTypeV2,
1420            /// The maximum acceptable surface gap computed between the cut surfaces. Must be
1421            /// positive (i.e. greater than zero).
1422            pub tolerance: LengthUnit,
1423            /// Which cutting algorithm to use.
1424            #[serde(default)]
1425            #[builder(default)]
1426            pub strategy: CutStrategy,
1427            /// What IDs should the resulting faces have?
1428            /// If you've only passed one edge ID, its ID will
1429            /// be the command ID used to send this command, and this
1430            /// field should be empty.
1431            /// If you've passed `n` IDs (to cut `n` edges), then
1432            /// this should be length `n-1`, and the first edge will use
1433            /// the command ID used to send this command.
1434            #[serde(default)]
1435            #[builder(default)]
1436            pub extra_face_ids: Vec<Uuid>,
1437            /// If true, use the legacy CSG algorithm.
1438            #[serde(default, skip_serializing_if = "super::is_false")]
1439            #[builder(default)]
1440            pub use_legacy: bool,
1441            /// Which version of the edge cut algorithm to use.
1442            #[serde(default, skip_serializing_if = "EdgeCutVersion::is_default")]
1443            #[builder(default)]
1444            pub version: EdgeCutVersion,
1445        }
1446
1447        /// Cut the list of given edges with the given cut parameters.
1448        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1449        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1450        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1451        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1452        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1453        pub struct Solid3dCutEdges {
1454            /// Which object is being cut.
1455            pub object_id: Uuid,
1456            /// Which edges you want to cut.
1457            #[serde(default)]
1458            #[builder(default)]
1459            pub edge_ids: Vec<Uuid>,
1460            /// The cut type and information required to perform the cut.
1461            pub cut_type: CutTypeV2,
1462            /// The maximum acceptable surface gap computed between the cut surfaces. Must be
1463            /// positive (i.e. greater than zero).
1464            pub tolerance: LengthUnit,
1465            /// Which cutting algorithm to use.
1466            #[serde(default)]
1467            #[builder(default)]
1468            pub strategy: CutStrategy,
1469            /// What IDs should the resulting faces have?
1470            /// If you've only passed one edge ID, its ID will
1471            /// be the command ID used to send this command, and this
1472            /// field should be empty.
1473            /// If you've passed `n` IDs (to cut `n` edges), then
1474            /// this should be length `n-1`, and the first edge will use
1475            /// the command ID used to send this command.
1476            #[serde(default)]
1477            #[builder(default)]
1478            pub extra_face_ids: Vec<Uuid>,
1479            /// If true, use the legacy CSG algorithm.
1480            #[serde(default, skip_serializing_if = "super::is_false")]
1481            #[builder(default)]
1482            pub use_legacy: bool,
1483            /// Which version of the edge cut algorithm to use.
1484            #[serde(default, skip_serializing_if = "EdgeCutVersion::is_default")]
1485            #[builder(default)]
1486            pub version: EdgeCutVersion,
1487        }
1488
1489        /// Determines whether a brep face is planar and returns its surface-local planar axes if so
1490        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1491        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1492        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1493        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1494        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1495        pub struct FaceIsPlanar {
1496            /// Which face is being queried.
1497            pub object_id: Uuid,
1498        }
1499
1500        /// Determines a position on a brep face evaluated by parameters u,v
1501        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1502        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1503        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1504        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1505        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1506        pub struct FaceGetPosition {
1507            /// Which face is being queried.
1508            pub object_id: Uuid,
1509
1510            /// The 2D parameter-space u,v position to evaluate the surface at
1511            pub uv: Point2d<f64>,
1512        }
1513
1514        ///Obtains the surface "center of mass"
1515        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1516        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1517        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1518        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1519        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1520        pub struct FaceGetCenter {
1521            /// Which face is being queried.
1522            pub object_id: Uuid,
1523        }
1524
1525        /// Determines the gradient (dFdu, dFdv) + normal vector on a brep face evaluated by parameters u,v
1526        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1527        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1528        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1529        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1530        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1531        pub struct FaceGetGradient {
1532            /// Which face is being queried.
1533            pub object_id: Uuid,
1534
1535            /// The 2D parameter-space u,v position to evaluate the surface at
1536            pub uv: Point2d<f64>,
1537        }
1538
1539        /// Send object to front or back.
1540        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1541        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1542        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1543        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1544        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1545        pub struct SendObject {
1546            /// Which object is being changed.
1547            pub object_id: Uuid,
1548            /// Bring to front = true, send to back = false.
1549            pub front: bool,
1550        }
1551        /// Set opacity of the entity.
1552        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1553        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1554        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1555        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1556        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1557        pub struct EntitySetOpacity {
1558            /// Which entity is being changed.
1559            pub entity_id: Uuid,
1560            /// How transparent should it be?
1561            /// 0 or lower is totally transparent.
1562            /// 1 or greater is totally opaque.
1563            pub opacity: f32,
1564        }
1565
1566        /// Fade entity in or out.
1567        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1568        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1569        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1570        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1571        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1572        pub struct EntityFade {
1573            /// Which entity is being changed.
1574            pub entity_id: Uuid,
1575            /// Fade in = true, fade out = false.
1576            pub fade_in: bool,
1577            /// How many seconds the animation should take.
1578            #[serde(default = "default_animation_seconds")]
1579            #[builder(default = default_animation_seconds())]
1580            pub duration_seconds: f64,
1581        }
1582
1583        /// Make a new plane
1584        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1585        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1586        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1587        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1588        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1589        pub struct MakePlane {
1590            /// Origin of the plane
1591            pub origin: Point3d<LengthUnit>,
1592            /// What should the plane's X axis be?
1593            pub x_axis: Point3d<f64>,
1594            /// What should the plane's Y axis be?
1595            pub y_axis: Point3d<f64>,
1596            /// What should the plane's span/extent?
1597            /// When rendered visually, this is both the
1598            /// width and height along X and Y axis respectively.
1599            pub size: LengthUnit,
1600            /// If true, any existing drawables within the obj will be replaced (the object will be reset)
1601            pub clobber: bool,
1602            /// If true, the plane will be created but hidden initially.
1603            pub hide: Option<bool>,
1604        }
1605
1606        /// Set the color of a plane.
1607        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1608        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1609        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1610        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1611        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1612        pub struct PlaneSetColor {
1613            /// Which plane is being changed.
1614            pub plane_id: Uuid,
1615            /// What color it should be.
1616            pub color: Color,
1617        }
1618
1619        /// Set the current tool.
1620        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1621        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1622        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1623        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1624        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1625        pub struct SetTool {
1626            /// What tool should be active.
1627            pub tool: SceneToolType,
1628        }
1629
1630        /// Send a mouse move event
1631        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1632        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1633        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1634        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1635        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1636        pub struct MouseMove {
1637            /// Where the mouse is
1638            pub window: Point2d,
1639            /// Logical timestamp. The client should increment this
1640            /// with every event in the current mouse drag. That way, if the
1641            /// events are being sent over an unordered channel, the API
1642            /// can ignore the older events.
1643            pub sequence: Option<u32>,
1644        }
1645
1646        /// Send a mouse click event
1647        /// Updates modified/selected entities.
1648        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1649        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1650        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1651        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1652        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1653        pub struct MouseClick {
1654            /// Where the mouse is
1655            pub window: Point2d,
1656        }
1657
1658        /// Disable sketch mode.
1659        /// If you are sketching on a face, be sure to not disable sketch mode until you have extruded.
1660        /// Otherwise, your object will not be fused with the face.
1661        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1662        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1663        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1664        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1665        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1666        pub struct SketchModeDisable {}
1667
1668        /// Get the plane for sketch mode.
1669        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1670        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1671        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1672        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1673        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1674        pub struct GetSketchModePlane {}
1675
1676        /// Get the plane for sketch mode.
1677        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1678        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1679        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1680        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1681        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1682        pub struct CurveSetConstraint {
1683            /// Which curve to constrain.
1684            pub object_id: Uuid,
1685            /// Which constraint to apply.
1686            pub constraint_bound: PathComponentConstraintBound,
1687            /// What part of the curve should be constrained.
1688            pub constraint_type: PathComponentConstraintType,
1689        }
1690
1691        /// Sketch on some entity (e.g. a plane, a face).
1692        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1693        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1694        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1695        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1696        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1697        pub struct EnableSketchMode {
1698            /// Which entity to sketch on.
1699            pub entity_id: Uuid,
1700            /// Should the camera use orthographic projection?
1701            /// In other words, should an object's size in the rendered image stay constant regardless of its distance from the camera.
1702            pub ortho: bool,
1703            /// Should we animate or snap for the camera transition?
1704            pub animated: bool,
1705            /// Should the camera move at all?
1706            pub adjust_camera: bool,
1707            /// If provided, ensures that the normal of the sketch plane must be aligned with this supplied normal
1708            /// (otherwise the camera position will be used to infer the normal to point towards the viewer)
1709            pub planar_normal: Option<Point3d<f64>>,
1710        }
1711
1712        /// Sets whether or not changes to the scene or its objects will be done as a "dry run"
1713        /// In a dry run, successful commands won't actually change the model.
1714        /// This is useful for catching errors before actually making the change.
1715        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1716        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1717        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1718        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1719        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1720        pub struct EnableDryRun {}
1721
1722        /// Sets whether or not changes to the scene or its objects will be done as a "dry run"
1723        /// In a dry run, successful commands won't actually change the model.
1724        /// This is useful for catching errors before actually making the change.
1725        #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1726        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1727        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1728        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1729        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1730        pub struct DisableDryRun {}
1731
1732        /// Set the background color of the scene.
1733        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1734        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1735        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1736        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1737        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1738        pub struct SetBackgroundColor {
1739            /// The color to set the background to.
1740            pub color: Color,
1741        }
1742
1743        /// Set the properties of the tool lines for the scene.
1744        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1745        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1746        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1747        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1748        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1749        pub struct SetCurrentToolProperties {
1750            /// The color to set the tool line to.
1751            pub color: Option<Color>,
1752        }
1753
1754        /// Set the default system properties used when a specific property isn't set.
1755        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1756        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1757        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1758        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1759        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1760        pub struct SetDefaultSystemProperties {
1761            /// The default system color.
1762            #[serde(default)]
1763            pub color: Option<Color>,
1764            /// The default color to use for all backfaces
1765            #[serde(default)]
1766            pub backface_color: Option<Color>,
1767            /// The default color to use for highlight
1768            #[serde(default)]
1769            pub highlight_color: Option<Color>,
1770            /// The default color to use for selection
1771            #[serde(default)]
1772            pub selection_color: Option<Color>,
1773        }
1774
1775        /// Get type of the given curve.
1776        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1777        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1778        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1779        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1780        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1781        pub struct CurveGetType {
1782            /// Which curve to query.
1783            pub curve_id: Uuid,
1784        }
1785
1786        /// Get control points of the given curve.
1787        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1788        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1789        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1790        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1791        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1792        pub struct CurveGetControlPoints {
1793            /// Which curve to query.
1794            pub curve_id: Uuid,
1795        }
1796
1797        /// Project an entity on to a plane.
1798        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1799        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1800        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1801        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1802        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1803        pub struct ProjectEntityToPlane {
1804            /// Which entity to project (vertex or edge). Legacy; if both `entity_id` and `entity_reference` are provided, `entity_reference` takes precedence.
1805            #[serde(default, skip_serializing_if = "Option::is_none")]
1806            pub entity_id: Option<Uuid>,
1807            /// Entity reference (e.g. edge by side_faces, vertex, face) to project. If both `entity_id` and `entity_reference` are provided, `entity_reference` takes precedence.
1808            #[serde(default, skip_serializing_if = "Option::is_none")]
1809            pub entity_reference: Option<EntityReference>,
1810            /// Which plane to project the entity onto.
1811            pub plane_id: Uuid,
1812            /// If true: the projected points are returned in the plane_id's coordinate system,
1813            /// else: the projected points are returned in the world coordinate system.
1814            pub use_plane_coords: bool,
1815        }
1816
1817        /// Project a list of points on to a plane.
1818        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1819        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1820        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1821        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1822        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1823        pub struct ProjectPointsToPlane {
1824            /// The id of the plane used for the projection.
1825            pub plane_id: Uuid,
1826            /// The list of points that will be projected.
1827            pub points: Vec<Point3d<f64>>,
1828            /// If true: the projected points are returned in the plane_id's coordinate sysetm.
1829            /// else: the projected points are returned in the world coordinate system.
1830            pub use_plane_coords: bool,
1831        }
1832
1833        /// Enum containing the variety of image formats snapshots may be exported to.
1834        #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, FromStr, Display)]
1835        #[serde(rename_all = "snake_case")]
1836        #[display(style = "snake_case")]
1837        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1838        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1839        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1840        #[cfg_attr(feature = "python", pyo3::pyclass(from_py_object), pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
1841        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1842        pub enum ImageFormat {
1843            /// .png format
1844            Png,
1845            /// .jpeg format
1846            Jpeg,
1847        }
1848
1849        /// Take a snapshot of the current view.
1850        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1851        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1852        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1853        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1854        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1855        pub struct TakeSnapshot {
1856            /// What image format to return.
1857            pub format: ImageFormat,
1858        }
1859
1860        /// Add a gizmo showing the axes.
1861        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1862        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1863        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1864        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1865        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1866        pub struct MakeAxesGizmo {
1867            /// If true, axes gizmo will be placed in the corner of the screen.
1868            /// If false, it will be placed at the origin of the scene.
1869            pub gizmo_mode: bool,
1870            /// If true, any existing drawables within the obj will be replaced (the object will be reset)
1871            pub clobber: bool,
1872        }
1873
1874        /// Query the given path.
1875        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1876        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1877        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1878        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1879        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1880        pub struct PathGetInfo {
1881            /// Which path to query
1882            pub path_id: Uuid,
1883        }
1884
1885        /// Obtain curve ids for vertex ids
1886        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1887        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1888        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1889        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1890        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1891        pub struct PathGetCurveUuidsForVertices {
1892            /// Which path to query
1893            pub path_id: Uuid,
1894
1895            /// IDs of the vertices for which to obtain curve ids from
1896            pub vertex_ids: Vec<Uuid>,
1897        }
1898
1899        /// Obtain curve id by index
1900        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1901        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1902        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1903        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1904        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1905        pub struct PathGetCurveUuid {
1906            /// Which path to query
1907            pub path_id: Uuid,
1908
1909            /// IDs of the vertices for which to obtain curve ids from
1910            pub index: u32,
1911        }
1912
1913        /// Obtain vertex ids for a path
1914        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1915        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1916        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1917        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1918        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1919        pub struct PathGetVertexUuids {
1920            /// Which path to query
1921            pub path_id: Uuid,
1922        }
1923
1924        /// Obtain the sketch target id (if the path was drawn in sketchmode) for a path
1925        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1926        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1927        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1928        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1929        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1930        pub struct PathGetSketchTargetUuid {
1931            /// Which path to query
1932            pub path_id: Uuid,
1933        }
1934
1935        /// Start dragging the mouse.
1936        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1937        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1938        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1939        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1940        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1941        pub struct HandleMouseDragStart {
1942            /// The mouse position.
1943            pub window: Point2d,
1944        }
1945
1946        /// Continue dragging the mouse.
1947        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1948        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1949        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1950        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1951        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1952        pub struct HandleMouseDragMove {
1953            /// The mouse position.
1954            pub window: Point2d,
1955            /// Logical timestamp. The client should increment this
1956            /// with every event in the current mouse drag. That way, if the
1957            /// events are being sent over an unordered channel, the API
1958            /// can ignore the older events.
1959            pub sequence: Option<u32>,
1960        }
1961
1962        /// Stop dragging the mouse.
1963        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1964        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1965        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1966        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1967        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1968        pub struct HandleMouseDragEnd {
1969            /// The mouse position.
1970            pub window: Point2d,
1971        }
1972
1973        /// Remove scene objects.
1974        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1975        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1976        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1977        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1978        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1979        pub struct RemoveSceneObjects {
1980            /// Objects to remove.
1981            pub object_ids: HashSet<Uuid>,
1982        }
1983
1984        /// Utility method. Performs both a ray cast and projection to plane-local coordinates.
1985        /// Returns the plane coordinates for the given window coordinates.
1986        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
1987        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1988        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
1989        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1990        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
1991        pub struct PlaneIntersectAndProject {
1992            /// The plane you're intersecting against.
1993            pub plane_id: Uuid,
1994            /// Window coordinates where the ray cast should be aimed.
1995            pub window: Point2d,
1996        }
1997
1998        /// Find the start and end of a curve.
1999        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2000        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2001        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2002        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2003        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2004        pub struct CurveGetEndPoints {
2005            /// ID of the curve being queried.
2006            pub curve_id: Uuid,
2007        }
2008
2009        /// Reconfigure the stream.
2010        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2011        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2012        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2013        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2014        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2015        pub struct ReconfigureStream {
2016            /// Width of the stream.
2017            pub width: u32,
2018            /// Height of the stream.
2019            pub height: u32,
2020            /// Frames per second.
2021            pub fps: u32,
2022            /// Video feed's constant bitrate (CBR)
2023            #[serde(default)]
2024            pub bitrate: Option<u32>,
2025        }
2026
2027        /// Import files to the current model.
2028        #[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2029        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2030        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2031        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2032        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2033        pub struct ImportFiles {
2034            /// Files to import.
2035            pub files: Vec<super::ImportFile>,
2036            /// Input file format.
2037            pub format: crate::format::InputFormat3d,
2038        }
2039
2040        /// Set the units of the scene.
2041        /// For all following commands, the units will be interpreted as the given units.
2042        /// Any previously executed commands will not be affected or have their units changed.
2043        /// They will remain in the units they were originally executed in.
2044        /// If not set, engine units default to mm.
2045        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2046        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2047        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2048        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2049        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2050        pub struct SetSceneUnits {
2051            /// Which units the scene uses.
2052            pub unit: units::UnitLength,
2053        }
2054
2055        /// Get the mass of entities in the scene or the default scene.
2056        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2057        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2058        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2059        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2060        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2061        pub struct Mass {
2062            /// IDs of the entities to get the mass of. If this is empty, then the default scene is included in
2063            /// the mass.
2064            #[builder(default)]
2065            pub entity_ids: Vec<Uuid>,
2066            /// The material density.
2067            pub material_density: f64,
2068            /// The material density unit.
2069            pub material_density_unit: units::UnitDensity,
2070            /// The output unit for the mass.
2071            pub output_unit: units::UnitMass,
2072        }
2073
2074        /// Get the density of entities in the scene or the default scene.
2075        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2076        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2077        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2078        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2079        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2080        pub struct Density {
2081            /// IDs of the entities to get the density of. If this is empty, then the default scene is included in
2082            /// the density.
2083            #[builder(default)]
2084            pub entity_ids: Vec<Uuid>,
2085            /// The material mass.
2086            pub material_mass: f64,
2087            /// The material mass unit.
2088            pub material_mass_unit: units::UnitMass,
2089            /// The output unit for the density.
2090            pub output_unit: units::UnitDensity,
2091        }
2092
2093        /// Get the volume of entities in the scene or the default scene.
2094        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2095        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2096        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2097        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2098        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2099        pub struct Volume {
2100            /// IDs of the entities to get the volume of. If this is empty, then the default scene is included in
2101            /// the volume.
2102            #[builder(default)]
2103            pub entity_ids: Vec<Uuid>,
2104            /// The output unit for the volume.
2105            pub output_unit: units::UnitVolume,
2106        }
2107
2108        /// Get the center of mass of entities in the scene or the default scene.
2109        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2110        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2111        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2112        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2113        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2114        pub struct CenterOfMass {
2115            /// IDs of the entities to get the center of mass of. If this is empty, then the default scene is included in
2116            /// the center of mass.
2117            #[builder(default)]
2118            pub entity_ids: Vec<Uuid>,
2119            /// The output unit for the center of mass.
2120            pub output_unit: units::UnitLength,
2121        }
2122
2123        /// Get the surface area of entities in the scene or the default scene.
2124        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2125        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2126        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2127        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2128        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2129        pub struct SurfaceArea {
2130            /// IDs of the entities to get the surface area of. If this is empty, then the default scene is included in
2131            /// the surface area.
2132            #[builder(default)]
2133            pub entity_ids: Vec<Uuid>,
2134            /// The output unit for the surface area.
2135            pub output_unit: units::UnitArea,
2136        }
2137
2138        /// Focus the default camera upon an object in the scene.
2139        #[derive(
2140            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2141            Builder
2142        )]
2143        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2144        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2145        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2146        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2147        pub struct DefaultCameraFocusOn {
2148            /// UUID of object to focus on.
2149            pub uuid: Uuid,
2150        }
2151        /// When you select some entity with the current tool, what should happen to the entity?
2152        #[derive(
2153            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2154            Builder
2155        )]
2156        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2157        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2158        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2159        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2160        pub struct SetSelectionType {
2161            /// What type of selection should occur when you select something?
2162            pub selection_type: SceneSelectionType,
2163        }
2164
2165        /// What kind of entities can be selected?
2166        #[derive(
2167            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2168            Builder
2169        )]
2170        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2171        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2172        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2173        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2174        pub struct SetSelectionFilter {
2175            /// If vector is empty, clear all filters.
2176            /// If vector is non-empty, only the given entity types will be selectable.
2177            pub filter: Vec<EntityType>,
2178        }
2179
2180        /// Get the ids of a given entity type.
2181        #[derive(
2182            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2183            Builder
2184        )]
2185        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2186        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2187        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2188        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2189        pub struct SceneGetEntityIds {
2190            /// The entity types to be queried.
2191            pub filter: Vec<EntityType>,
2192            /// Skip the first n returned ids. If multiple filters are provided, this skip will
2193            /// apply to each filter individually.
2194            pub skip: u32,
2195            /// Take n ids after any ids skipped. This value must be greater than zero and not
2196            /// exceed 1000. If multiple filters are provided, this take will apply to each filter
2197            /// individually. If there are fewer than `take` items of the provided filter type then the
2198            /// returned list's length will be the smaller value.
2199            #[schemars(range(min = 1, max = 1000))]
2200            pub take: u32,
2201        }
2202
2203        /// Use orthographic projection.
2204        #[derive(
2205            Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2206            Builder
2207        )]
2208        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2209        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2210        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2211        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2212        pub struct DefaultCameraSetOrthographic {}
2213
2214        /// Use perspective projection.
2215        #[derive(
2216            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2217            Builder
2218        )]
2219        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2220        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2221        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2222        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2223        pub struct DefaultCameraSetPerspective {
2224            /// If this is not given, use the same parameters as last time the perspective camera was used.
2225            pub parameters: Option<PerspectiveCameraParameters>,
2226        }
2227
2228        ///Updates the camera to center to the center of the current selection
2229        ///(or the origin if nothing is selected)
2230        #[derive(
2231            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder
2232        )]
2233        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2234        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2235        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2236        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2237        pub struct DefaultCameraCenterToSelection {
2238            /// Dictates whether or not the camera position should be adjusted during this operation
2239            /// If no movement is requested, the camera will orbit around the new center from its current position
2240            #[serde(default)]
2241            #[builder(default)]
2242            pub camera_movement: CameraMovement,
2243        }
2244
2245        ///Updates the camera to center to the center of the current scene's bounds
2246        #[derive(
2247            Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder
2248        )]
2249        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2250        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2251        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2252        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2253        pub struct DefaultCameraCenterToScene {
2254            /// Dictates whether or not the camera position should be adjusted during this operation
2255            /// If no movement is requested, the camera will orbit around the new center from its current position
2256            #[serde(default)]
2257            #[builder(default)]
2258            pub camera_movement: CameraMovement,
2259        }
2260
2261        /// Fit the view to the specified object(s).
2262        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2263        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2264        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2265        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2266        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2267        pub struct ZoomToFit {
2268            /// Which objects to fit camera to; if empty, fit to all non-default objects. Defaults to empty vector.
2269            #[serde(default)]
2270            #[builder(default)]
2271            pub object_ids: Vec<Uuid>,
2272            /// How much to pad the view frame by, as a fraction of the object(s) bounding box size.
2273            /// Negative padding will crop the view of the object proportionally.
2274            /// e.g. padding = 0.2 means the view will span 120% of the object(s) bounding box,
2275            /// and padding = -0.2 means the view will span 80% of the object(s) bounding box.
2276            #[serde(default)]
2277            #[builder(default)]
2278            pub padding: f32,
2279            /// Whether or not to animate the camera movement.
2280            #[serde(default)]
2281            #[builder(default)]
2282            pub animated: bool,
2283        }
2284
2285        /// Looks along the normal of the specified face (if it is planar!), and fits the view to it.
2286        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2287        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2288        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2289        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2290        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2291        pub struct OrientToFace {
2292            /// Which face to orient camera to. If the face is not planar, no action will occur.
2293            pub face_id: Uuid,
2294            /// How much to pad the view frame by, as a fraction of the face bounding box size.
2295            /// Negative padding will crop the view of the face proportionally.
2296            /// e.g. padding = 0.2 means the view will span 120% of the face bounding box,
2297            /// and padding = -0.2 means the view will span 80% of the face bounding box.
2298            #[serde(default)]
2299            #[builder(default)]
2300            pub padding: f32,
2301            /// Whether or not to animate the camera movement. (Animation is currently not supported.)
2302            #[serde(default)]
2303            #[builder(default)]
2304            pub animated: bool,
2305        }
2306
2307        /// Fit the view to the scene with an isometric view.
2308        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2309        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2310        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2311        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2312        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2313        pub struct ViewIsometric {
2314            /// How much to pad the view frame by, as a fraction of the object(s) bounding box size.
2315            /// Negative padding will crop the view of the object proportionally.
2316            /// e.g. padding = 0.2 means the view will span 120% of the object(s) bounding box,
2317            /// and padding = -0.2 means the view will span 80% of the object(s) bounding box.
2318            #[serde(default)]
2319            #[builder(default)]
2320            pub padding: f32,
2321        }
2322
2323        /// Get a concise description of all of an extrusion's faces.
2324        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2325        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2326        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2327        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2328        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2329        pub struct Solid3dGetExtrusionFaceInfo {
2330            /// The Solid3d object whose extrusion is being queried.
2331            pub object_id: Uuid,
2332            /// Any edge that lies on the extrusion base path.
2333            pub edge_id: Uuid,
2334        }
2335
2336        /// Get a concise description of all of solids edges.
2337        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2338        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2339        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2340        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2341        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2342        pub struct Solid3dGetAdjacencyInfo {
2343            /// The Solid3d object whose info is being queried.
2344            pub object_id: Uuid,
2345            /// Any edge that lies on the extrusion base path.
2346            pub edge_id: Uuid,
2347        }
2348
2349
2350        /// Clear the selection
2351        #[derive(Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2352        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2353        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2354        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2355        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2356        pub struct SelectClear {}
2357
2358        /// Set the selection to exactly these entities (replaces previous selection).
2359        /// Empty array clears the selection.
2360        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2361        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2362        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2363        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2364        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2365        pub struct SelectEntity {
2366            /// Which entities to select (face-based references for edges/vertices, face_id for faces)
2367            pub entities: Vec<EntityReference>,
2368        }
2369
2370        /// Find all IDs of selected entities
2371        #[derive(Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2372        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2373        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2374        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2375        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2376        pub struct SelectGet {}
2377
2378        /// Get the number of objects in the scene
2379        #[derive(
2380            Clone, Debug, Default, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant,
2381            Builder
2382        )]
2383        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2384        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2385        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2386        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2387        pub struct GetNumObjects {}
2388
2389        ///Set the transform of an object.
2390        #[derive(
2391            Clone, Debug, Deserialize, PartialEq, JsonSchema, Serialize, ModelingCmdVariant,
2392            Builder
2393        )]
2394        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2395        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2396        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2397        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2398        pub struct SetObjectTransform
2399        {
2400            /// Id of the object whose transform is to be set.
2401            pub object_id: Uuid,
2402            /// List of transforms to be applied to the object.
2403            pub transforms: Vec<ComponentTransform>,
2404        }
2405
2406        /// Create a new solid from combining other smaller solids.
2407        /// In other words, every part of the input solids will be included in the output solid.
2408        #[derive(
2409            Clone, Debug, Deserialize, PartialEq, JsonSchema, Serialize, ModelingCmdVariant,
2410            Builder
2411        )]
2412        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2413        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2414        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2415        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2416        pub struct BooleanUnion
2417        {
2418            /// Which solids to union together.
2419            /// Cannot be empty.
2420            pub solid_ids: Vec<Uuid>,
2421            /// If true, non-contiguous bodies in the result will be returned as separate objects
2422            #[serde(default)]
2423            #[builder(default)]
2424            pub separate_bodies: bool,
2425            /// If true, use the legacy CSG algorithm.
2426            #[serde(default, skip_serializing_if = "super::is_false")]
2427            #[builder(default)]
2428            pub use_legacy: bool,
2429            /// The maximum acceptable surface gap computed between the joined solids. Must be positive (i.e. greater than zero).
2430            pub tolerance: LengthUnit,
2431        }
2432
2433        /// Create a new solid from intersecting several other solids.
2434        /// In other words, the part of the input solids where they all overlap will be the output solid.
2435        #[derive(
2436            Clone, Debug, Deserialize, PartialEq, JsonSchema, Serialize, ModelingCmdVariant,
2437            Builder
2438        )]
2439        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2440        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2441        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2442        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2443        pub struct BooleanIntersection
2444        {
2445            /// Which solids to intersect together
2446            pub solid_ids: Vec<Uuid>,
2447            /// If true, non-contiguous bodies in the result will be returned as separate objects
2448            #[serde(default)]
2449            #[builder(default)]
2450            pub separate_bodies: bool,
2451            /// If true, use the legacy CSG algorithm.
2452            #[serde(default, skip_serializing_if = "super::is_false")]
2453            #[builder(default)]
2454            pub use_legacy: bool,
2455            /// The maximum acceptable surface gap computed between the joined solids. Must be positive (i.e. greater than zero).
2456            pub tolerance: LengthUnit,
2457        }
2458
2459        /// Create a new solid from subtracting several other solids.
2460        /// The 'target' is what will be cut from.
2461        /// The 'tool' is what will be cut out from 'target'.
2462        #[derive(
2463            Clone, Debug, Deserialize, PartialEq, JsonSchema, Serialize, ModelingCmdVariant,
2464            Builder
2465        )]
2466        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2467        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2468        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2469        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2470        pub struct BooleanSubtract
2471        {
2472            /// Geometry to cut out from.
2473            pub target_ids: Vec<Uuid>,
2474            /// Will be cut out from the 'target'.
2475            pub tool_ids: Vec<Uuid>,
2476            /// If true, non-contiguous bodies in the result will be returned as separate objects
2477            #[serde(default)]
2478            #[builder(default)]
2479            pub separate_bodies: bool,
2480            /// If true, use the legacy CSG algorithm.
2481            #[serde(default, skip_serializing_if = "super::is_false")]
2482            #[builder(default)]
2483            pub use_legacy: bool,
2484            /// The maximum acceptable surface gap computed between the target and the solids cut out from it. Must be positive (i.e. greater than zero).
2485            pub tolerance: LengthUnit,
2486        }
2487
2488        /// Create a new non-manifold body by intersecting all the input bodies, cutting and splitting all the faces at the intersection boundaries.
2489        #[derive(
2490            Clone, Debug, Deserialize, PartialEq, JsonSchema, Serialize, ModelingCmdVariant,
2491            Builder
2492        )]
2493        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2494        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2495        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2496        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2497        pub struct BooleanImprint
2498        {
2499            /// Which target input bodies to intersect. Inputs with non-solid body types are permitted
2500            #[serde(alias = "target_ids")]
2501            pub body_ids: Vec<Uuid>,
2502            ///If provided, only these bodies will be used to intersect with the target bodies in body_ids,
2503            ///Otherwise, all bodies in body_ids will be intersected with themselves.
2504            #[serde(default)]
2505            pub tool_ids: Option<Vec<Uuid>>,
2506            /// If true, target bodies will be separated into multiple objects at their intersection boundaries.
2507            #[serde(default)]
2508            #[builder(default)]
2509            pub separate_bodies: bool,
2510            /// If true, use the legacy CSG algorithm.
2511            #[serde(default, skip_serializing_if = "super::is_false")]
2512            #[builder(default)]
2513            pub use_legacy: bool,
2514            /// If true, the provided tool bodies will not be modified
2515            #[serde(default)]
2516            #[builder(default)]
2517            pub keep_tools: bool,
2518            /// The maximum acceptable surface gap between the intersected bodies. Must be positive (i.e. greater than zero).
2519            pub tolerance: LengthUnit,
2520        }
2521
2522        /// Make a new path by offsetting an object by a given distance.
2523        /// The new path's ID will be the ID of this command.
2524        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2525        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2526        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2527        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2528        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2529        pub struct MakeOffsetPath {
2530            /// The object that will be offset (can be a path, sketch, or a solid)
2531            pub object_id: Uuid,
2532            /// If the object is a solid, this is the ID of the face to base the offset on.
2533            /// If given, and `object_id` refers to a solid, then this face on the solid will be offset.
2534            /// If given but `object_id` doesn't refer to a solid, responds with an error.
2535            /// If not given, then `object_id` itself will be offset directly.
2536            #[serde(default)]
2537            pub face_id: Option<Uuid>,
2538            /// The distance to offset the path (positive for outset, negative for inset)
2539            pub offset: LengthUnit,
2540        }
2541
2542        /// Add a hole to a closed path by offsetting it a uniform distance inward.
2543        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2544        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2545        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2546        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2547        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2548        pub struct AddHoleFromOffset {
2549            /// The closed path to add a hole to.
2550            pub object_id: Uuid,
2551            /// The distance to offset the path (positive for outset, negative for inset)
2552            pub offset: LengthUnit,
2553        }
2554
2555        /// Align the grid with a plane or a planar face.
2556        #[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, ModelingCmdVariant, Builder)]
2557        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2558        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2559        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2560        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2561        pub struct SetGridReferencePlane {
2562            /// The grid to be moved.
2563            pub grid_id: Uuid,
2564            /// The plane or face that the grid will be aligned to.
2565            /// If a face, it must be planar to succeed.
2566            pub reference_id: Uuid,
2567        }
2568
2569        /// Set the scale of the grid lines in the video feed.
2570        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2571        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2572        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2573        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2574        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2575        pub struct SetGridScale {
2576            /// Distance between grid lines represents this much distance.
2577            pub value: f32,
2578            /// Which units the `value` field uses.
2579            pub units: units::UnitLength,
2580        }
2581
2582        /// Set the grid lines to auto scale. The grid will get larger the further you zoom out,
2583        /// and smaller the more you zoom in.
2584        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2585        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2586        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2587        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2588        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2589        pub struct SetGridAutoScale {
2590        }
2591
2592        /// Render transparent surfaces more accurately, but this might make rendering slower.
2593        /// Because it can interfere with runtime performance, it defaults to false.
2594        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2595        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2596        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2597        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2598        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2599        pub struct SetOrderIndependentTransparency {
2600            /// Enables or disables OIT.
2601            /// If not given, toggles it.
2602            pub enabled: Option<bool>,
2603        }
2604
2605        /// Create a region bounded by the intersection of various paths.
2606        /// The region should have an ID taken from the ID of the
2607        /// 'CreateRegion' modeling command.
2608        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2609        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2610        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2611        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2612        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2613        pub struct CreateRegion {
2614            /// Which sketch object to create the region from.
2615            pub object_id: Uuid,
2616            /// First segment to follow to find the region.
2617            pub segment: Uuid,
2618            /// Second segment to follow to find the region.
2619            /// Intersects the first segment.
2620            pub intersection_segment: Uuid,
2621            /// At which intersection between `segment` and `intersection_segment`
2622            /// should we stop following the `segment` and start following `intersection_segment`?
2623            /// Defaults to -1, which means the last intersection.
2624            #[serde(default = "super::negative_one")]
2625            #[builder(default = super::negative_one())]
2626            pub intersection_index: i32,
2627            /// By default, curve counterclockwise at intersections.
2628            /// If this is true, instead curve clockwise.
2629            #[serde(default)]
2630            #[builder(default)]
2631            pub curve_clockwise: bool,
2632            /// Which version of the Region endpoint to call.
2633            #[serde(default, skip_serializing_if = "RegionVersion::is_zero")]
2634            #[builder(default)]
2635            pub version: RegionVersion,
2636        }
2637
2638        /// Finds a suitable set of arguments that can be passed to CreateRegion to resolve this very region.
2639        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2640        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2641        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2642        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2643        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2644        pub struct RegionGetResolvableIntersectionInfo {
2645            /// Which region to resolve
2646            pub region_id: Uuid,
2647        }
2648
2649        /// Create a region with a query point.
2650        /// The region should have an ID taken from the ID of the
2651        /// 'CreateRegionFromQueryPoint' modeling command.
2652        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2653        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2654        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2655        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2656        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2657        pub struct CreateRegionFromQueryPoint {
2658            /// Which sketch object to create the region from.
2659            pub object_id: Uuid,
2660
2661            /// The query point (in the same coordinates as the sketch itself)
2662            /// if a possible sketch region contains this point, then that region will be created
2663            pub query_point: Point2d<LengthUnit>,
2664            /// Which version of the Region endpoint to call.
2665            #[serde(default, skip_serializing_if = "RegionVersion::is_zero")]
2666            #[builder(default)]
2667            pub version: RegionVersion,
2668        }
2669
2670        /// Finds a suitable point inside the region for calling such that CreateRegionFromQueryPoint will generate an identical region.
2671        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2672        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2673        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2674        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2675        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2676        pub struct RegionGetQueryPoint {
2677            /// Which region to search within
2678            pub region_id: Uuid,
2679        }
2680
2681        /// The user clicked on a point in the window,
2682        /// returns the region the user clicked on, if any.
2683        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2684        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2685        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2686        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2687        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2688        pub struct SelectRegionFromPoint {
2689            /// Where in the window was selected
2690            pub selected_at_window: Point2d,
2691        }
2692
2693        /// Get the smallest box that could contain the given parts.
2694        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2695        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2696        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2697        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2698        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2699        pub struct BoundingBox {
2700            /// IDs of the entities to be included in the box.
2701            /// If this is empty, then all entities are included (the entire scene).
2702            #[builder(default)]
2703            pub entity_ids: Vec<Uuid>,
2704            /// The output unit for the box's dimensions. Defaults to millimeters.
2705            #[builder(default = mm())]
2706            #[serde(default = "mm")]
2707            pub output_unit: units::UnitLength,
2708        }
2709
2710        ///Offset a surface by a given distance.
2711        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2712        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2713        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2714        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2715        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2716        pub struct OffsetSurface {
2717            /// The surface to offset.
2718            pub surface_id: Uuid,
2719            /// The distance to offset the surface by.
2720            pub distance: LengthUnit,
2721            /// Flip the newly created face.
2722            pub flip: bool,
2723        }
2724
2725        /// Returns the closest edge to this point.
2726        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, ModelingCmdVariant, Builder)]
2727        #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2728        #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2729        #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2730        #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2731        pub struct ClosestEdge {
2732            /// The body whose edges are being queried.
2733            /// If not given, will search all bodies in the scene.
2734            #[serde(default)]
2735            pub object_id: Option<Uuid>,
2736            /// Find the edge closest to this point.
2737            /// Assumed to be in absolute coordinates, relative to global (scene) origin.
2738            pub closest_to: Point3d<f64>,
2739        }
2740    }
2741}
2742
2743pub(crate) fn is_false(b: &bool) -> bool {
2744    !b
2745}
2746
2747pub(crate) fn negative_one() -> i32 {
2748    -1
2749}
2750
2751impl ModelingCmd {
2752    /// Is this command safe to run in an engine batch?
2753    pub fn is_safe_to_batch(&self) -> bool {
2754        use ModelingCmd::*;
2755        matches!(
2756            self,
2757            MovePathPen(_)
2758                | ExtendPath(_)
2759                | Extrude(_)
2760                | Revolve(_)
2761                | Solid3dFilletEdge(_)
2762                | ClosePath(_)
2763                | UpdateAnnotation(_)
2764                | ObjectVisible(_)
2765                | ObjectBringToFront(_)
2766                | Solid2dAddHole(_)
2767                | SendObject(_)
2768                | EntitySetOpacity(_)
2769                | PlaneSetColor(_)
2770                | SetTool(_)
2771        )
2772    }
2773}
2774
2775/// File to import into the current model.
2776/// If you are sending binary data for a file, be sure to send the WebSocketRequest as
2777/// binary/bson, not text/json.
2778#[derive(Clone, Serialize, Deserialize, JsonSchema, Eq, PartialEq, bon::Builder)]
2779#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
2780#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
2781#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
2782#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
2783pub struct ImportFile {
2784    /// The file's full path, including file extension.
2785    pub path: String,
2786    /// The raw bytes of the file
2787    #[serde(
2788        serialize_with = "serde_bytes::serialize",
2789        deserialize_with = "serde_bytes::deserialize"
2790    )]
2791    pub data: Vec<u8>,
2792}
2793
2794impl std::fmt::Debug for ImportFile {
2795    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2796        f.debug_struct("ImportFile")
2797            .field("path", &self.path)
2798            .field("data", &"<redacted>")
2799            .finish()
2800    }
2801}