1use enum_iterator::Sequence;
2use parse_display_derive::{Display, FromStr};
3pub use point::{Point2d, Point3d, Point4d, Quaternion};
4use schemars::{schema::SchemaObject, JsonSchema};
5use serde::{Deserialize, Serialize};
6use uuid::Uuid;
7
8#[cfg(feature = "cxx")]
9use crate::impl_extern_type;
10use crate::{length_unit::LengthUnit, output::ExtrusionFaceInfo, units::UnitAngle};
11
12mod point;
13
14#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
16#[serde(rename_all = "snake_case")]
17#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
18#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
19pub enum CutType {
20 #[default]
22 Fillet,
23 Chamfer,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
29#[serde(rename_all = "snake_case")]
30#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
31#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
32pub struct Rotation {
33 pub axis: Point3d<f64>,
36 pub angle: Angle,
39 pub origin: OriginType,
41}
42
43impl Default for Rotation {
44 fn default() -> Self {
46 Self {
47 axis: z_axis(),
48 angle: Angle::default(),
49 origin: OriginType::Local,
50 }
51 }
52}
53
54#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
56#[serde(rename_all = "snake_case")]
57#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
58#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
59pub struct Transform {
60 #[serde(default)]
63 pub translate: Point3d<LengthUnit>,
64 #[serde(default = "same_scale")]
67 pub scale: Point3d<f64>,
68 #[serde(default)]
71 pub rotation: Rotation,
72 #[serde(default = "bool_true")]
74 pub replicate: bool,
75}
76
77impl Default for Transform {
78 fn default() -> Self {
79 Self {
80 scale: same_scale(),
81 replicate: true,
82 translate: Default::default(),
83 rotation: Rotation::default(),
84 }
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
90#[serde(rename_all = "snake_case")]
91#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
92#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
93pub struct AnnotationOptions {
94 pub text: Option<AnnotationTextOptions>,
96 pub line_ends: Option<AnnotationLineEndOptions>,
98 pub line_width: Option<f32>,
100 pub color: Option<Color>,
102 pub position: Option<Point3d<f32>>,
104 pub dimension: Option<AnnotationBasicDimension>,
106 pub feature_control: Option<AnnotationFeatureControl>,
108 pub feature_tag: Option<AnnotationFeatureTag>,
110}
111
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
114#[serde(rename_all = "snake_case")]
115#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
116#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
117pub struct AnnotationLineEndOptions {
118 pub start: AnnotationLineEnd,
120 pub end: AnnotationLineEnd,
122}
123
124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
126#[serde(rename_all = "snake_case")]
127#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
128#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
129pub struct AnnotationTextOptions {
130 pub x: AnnotationTextAlignmentX,
132 pub y: AnnotationTextAlignmentY,
134 pub text: String,
136 pub point_size: u32,
138}
139
140#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
142#[serde(rename_all = "snake_case")]
143#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
144#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
145pub struct AnnotationMbdControlFrame {
146 pub symbol: MbdSymbol,
148 pub diameter_symbol: Option<MbdSymbol>,
150 pub tolerance: f64,
152 pub modifier: Option<MbdSymbol>,
154 pub primary_datum: Option<char>,
156 pub secondary_datum: Option<char>,
158 pub tertiary_datum: Option<char>,
160}
161
162#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
164#[serde(rename_all = "snake_case")]
165#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
166#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
167pub struct AnnotationMbdBasicDimension {
168 pub symbol: Option<MbdSymbol>,
170 pub dimension: Option<f64>,
172 pub tolerance: f64,
174}
175
176#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
178#[serde(rename_all = "snake_case")]
179#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
180#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
181pub struct AnnotationBasicDimension {
182 pub from_entity_id: Uuid,
184
185 pub from_entity_pos: Point2d<f64>,
187
188 pub to_entity_id: Uuid,
190
191 pub to_entity_pos: Point2d<f64>,
193
194 pub dimension: AnnotationMbdBasicDimension,
196
197 pub plane_id: Uuid,
199
200 pub offset: Point2d<f64>,
202
203 pub precision: u32,
205
206 pub font_scale: f32,
208
209 pub font_point_size: u32,
211}
212
213#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
215#[serde(rename_all = "snake_case")]
216#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
217#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
218pub struct AnnotationFeatureControl {
219 pub entity_id: Uuid,
221
222 pub entity_pos: Point2d<f64>,
224
225 pub leader_type: AnnotationLineEnd,
227
228 pub dimension: Option<AnnotationMbdBasicDimension>,
230
231 pub control_frame: Option<AnnotationMbdControlFrame>,
233
234 pub defined_datum: Option<char>,
236
237 pub prefix: Option<String>,
239
240 pub suffix: Option<String>,
242
243 pub plane_id: Uuid,
245
246 pub offset: Point2d<f64>,
248
249 pub precision: u32,
251
252 pub font_scale: f32,
254
255 pub font_point_size: u32,
257}
258
259#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
261#[serde(rename_all = "snake_case")]
262#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
263#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
264pub struct AnnotationFeatureTag {
265 pub entity_id: Uuid,
267
268 pub entity_pos: Point2d<f64>,
270
271 pub leader_type: AnnotationLineEnd,
273
274 pub key: String,
276
277 pub value: String,
279
280 pub show_key: bool,
282
283 pub plane_id: Uuid,
285
286 pub offset: Point2d<f64>,
288
289 pub font_scale: f32,
291
292 pub font_point_size: u32,
294}
295
296#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
300#[serde(rename_all = "snake_case", tag = "type")]
301#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
302#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
303pub enum DistanceType {
304 Euclidean {},
306 OnAxis {
308 axis: GlobalAxis,
310 },
311}
312
313#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
315#[serde(rename_all = "snake_case", tag = "type")]
316#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
317#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
318pub enum OriginType {
319 #[default]
321 Local,
322 Global,
324 Custom {
326 origin: Point3d<f64>,
328 },
329}
330
331#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
333#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
334#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
335pub struct Color {
336 pub r: f32,
338 pub g: f32,
340 pub b: f32,
342 pub a: f32,
344}
345
346#[allow(missing_docs)]
348#[derive(
349 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
350)]
351#[serde(rename_all = "lowercase")]
352#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
353#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
354pub enum AnnotationTextAlignmentX {
355 Left,
356 Center,
357 Right,
358}
359
360#[allow(missing_docs)]
362#[derive(
363 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
364)]
365#[serde(rename_all = "lowercase")]
366#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
367#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
368pub enum AnnotationTextAlignmentY {
369 Bottom,
370 Center,
371 Top,
372}
373
374#[allow(missing_docs)]
376#[derive(
377 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
378)]
379#[serde(rename_all = "lowercase")]
380#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
381#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
382pub enum AnnotationLineEnd {
383 None,
384 Arrow,
385 Dot,
386}
387
388#[derive(
390 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
391)]
392#[serde(rename_all = "lowercase")]
393#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
394#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
395pub enum AnnotationType {
396 T2D,
398 T3D,
400}
401
402#[derive(
404 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
405)]
406#[serde(rename_all = "lowercase")]
407#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
408#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
409pub enum MbdStandard {
410 AsmeY14_5,
412}
413
414#[allow(missing_docs)]
417#[derive(
418 Default,
419 Display,
420 FromStr,
421 Copy,
422 Eq,
423 PartialEq,
424 Debug,
425 JsonSchema,
426 Deserialize,
427 Serialize,
428 Sequence,
429 Clone,
430 Ord,
431 PartialOrd,
432)]
433#[serde(rename_all = "lowercase")]
434#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
435#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
436#[repr(u16)]
437pub enum MbdSymbol {
438 #[default]
439 None = 0,
440 ArcLength = 174,
441 Between = 175,
442 Degrees = 176,
443 PlusMinus = 177,
444 Angularity = 178,
445 Cylindricity = 179,
446 Roundness = 180,
447 Concentricity = 181,
448 Straightness = 182,
449 Parallelism = 183,
450 Flatness = 184,
451 ProfileOfLine = 185,
452 SurfaceProfile = 186,
453 Symmetry = 187,
454 Perpendicularity = 188,
455 Runout = 189,
456 TotalRunout = 190,
457 Position = 191,
458 CenterLine = 192,
459 PartingLine = 193,
460 IsoEnvelope = 195,
461 IsoEnvelopeNonY145M = 196,
462 FreeState = 197,
463 StatisticalTolerance = 198,
464 ContinuousFeature = 199,
465 Independency = 200,
466 Depth = 201,
467 Start = 202,
468 LeastCondition = 203,
469 MaxCondition = 204,
470 ConicalTaper = 205,
471 Projected = 206,
472 Slope = 207,
473 Micro = 208,
474 TangentPlane = 210,
475 Unilateral = 211,
476 SquareFeature = 212,
477 Countersink = 213,
478 SpotFace = 214,
479 Target = 215,
480 Diameter = 216,
481 Radius = 217,
482 SphericalRadius = 218,
483 SphericalDiameter = 219,
484 ControlledRadius = 220,
485 BoxStart = 123,
486 BoxBar = 162,
487 BoxBarBetween = 124,
488 LetterBackwardUnderline = 95,
489 PunctuationBackwardUnderline = 92,
490 ModifierBackwardUnderline = 126,
491 NumericBackwardUnderline = 96,
492 BoxEnd = 125,
493 DatumUp = 166,
494 DatumLeft = 168,
495 DatumRight = 167,
496 DatumDown = 165,
497 DatumTriangle = 295,
498 HalfSpace = 236,
499 QuarterSpace = 237,
500 EighthSpace = 238,
501 ModifierSpace = 239,
502}
503
504#[derive(
506 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
507)]
508#[serde(rename_all = "lowercase")]
509#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
510#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
511pub enum CameraDragInteractionType {
512 Pan,
514 Rotate,
516 RotateTrackball,
518 Zoom,
520}
521
522#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
525#[serde(rename_all = "snake_case", tag = "type")]
526#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
527#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
528pub enum PathSegment {
529 Line {
532 end: Point3d<LengthUnit>,
534 relative: bool,
536 },
537 Arc {
540 center: Point2d<LengthUnit>,
542 radius: LengthUnit,
544 start: Angle,
546 end: Angle,
548 relative: bool,
550 },
551 Bezier {
555 control1: Point3d<LengthUnit>,
557 control2: Point3d<LengthUnit>,
559 end: Point3d<LengthUnit>,
561 relative: bool,
563 },
564 TangentialArc {
566 radius: LengthUnit,
569 offset: Angle,
571 },
572 TangentialArcTo {
575 to: Point3d<LengthUnit>,
579 angle_snap_increment: Option<Angle>,
581 },
582 ArcTo {
584 interior: Point3d<LengthUnit>,
586 end: Point3d<LengthUnit>,
588 relative: bool,
590 },
591 CircularInvolute {
594 start_radius: LengthUnit,
597 end_radius: LengthUnit,
600 angle: Angle,
603 reverse: bool,
606 },
607 Ellipse {
609 center: Point2d<LengthUnit>,
611 major_axis: Point2d<LengthUnit>,
613 minor_radius: LengthUnit,
615 start_angle: Angle,
617 end_angle: Angle,
619 },
620 ConicTo {
623 interior: Point2d<LengthUnit>,
625 end: Point2d<LengthUnit>,
627 start_tangent: Point2d<LengthUnit>,
629 end_tangent: Point2d<LengthUnit>,
631 relative: bool,
633 },
634}
635
636#[derive(Clone, Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
638#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
639#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
640pub struct Angle {
641 pub unit: UnitAngle,
643 pub value: f64,
645}
646
647impl Angle {
648 pub fn to_degrees(self) -> f64 {
650 match self.unit {
651 UnitAngle::Degrees => self.value,
652 UnitAngle::Radians => self.value.to_degrees(),
653 }
654 }
655 pub fn to_radians(self) -> f64 {
657 match self.unit {
658 UnitAngle::Degrees => self.value.to_radians(),
659 UnitAngle::Radians => self.value,
660 }
661 }
662 pub const fn from_degrees(value: f64) -> Self {
664 Self {
665 unit: UnitAngle::Degrees,
666 value,
667 }
668 }
669 pub const fn from_radians(value: f64) -> Self {
671 Self {
672 unit: UnitAngle::Radians,
673 value,
674 }
675 }
676 pub const fn turn() -> Self {
678 Self::from_degrees(360.0)
679 }
680 pub const fn half_circle() -> Self {
682 Self::from_degrees(180.0)
683 }
684 pub const fn quarter_circle() -> Self {
686 Self::from_degrees(90.0)
687 }
688 pub const fn zero() -> Self {
690 Self::from_degrees(0.0)
691 }
692}
693
694impl Default for Angle {
696 fn default() -> Self {
698 Self::zero()
699 }
700}
701
702impl PartialOrd for Angle {
703 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
704 match (self.unit, other.unit) {
705 (UnitAngle::Degrees, UnitAngle::Degrees) => self.value.partial_cmp(&other.value),
707 (UnitAngle::Radians, UnitAngle::Radians) => self.value.partial_cmp(&other.value),
708 _ => self.to_degrees().partial_cmp(&other.to_degrees()),
709 }
710 }
711}
712
713impl std::ops::Add for Angle {
714 type Output = Self;
715
716 fn add(self, rhs: Self) -> Self::Output {
717 Self {
718 unit: UnitAngle::Degrees,
719 value: self.to_degrees() + rhs.to_degrees(),
720 }
721 }
722}
723
724impl std::ops::AddAssign for Angle {
725 fn add_assign(&mut self, rhs: Self) {
726 match self.unit {
727 UnitAngle::Degrees => {
728 self.value += rhs.to_degrees();
729 }
730 UnitAngle::Radians => {
731 self.value += rhs.to_radians();
732 }
733 }
734 }
735}
736
737#[derive(
739 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
740)]
741#[serde(rename_all = "lowercase")]
742#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
743#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
744pub enum SceneSelectionType {
745 Replace,
747 Add,
749 Remove,
751}
752
753#[allow(missing_docs)]
755#[derive(
756 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
757)]
758#[serde(rename_all = "snake_case")]
759#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
760#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
761pub enum SceneToolType {
762 CameraRevolve,
763 Select,
764 Move,
765 SketchLine,
766 SketchTangentialArc,
767 SketchCurve,
768 SketchCurveMod,
769}
770
771#[allow(missing_docs)]
773#[derive(
774 Display,
775 FromStr,
776 Copy,
777 Eq,
778 PartialEq,
779 Debug,
780 JsonSchema,
781 Deserialize,
782 Serialize,
783 Sequence,
784 Clone,
785 Ord,
786 PartialOrd,
787 Default,
788)]
789#[serde(rename_all = "snake_case")]
790#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
791#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
792pub enum PathComponentConstraintBound {
793 #[default]
794 Unconstrained,
795 PartiallyConstrained,
796 FullyConstrained,
797}
798
799#[allow(missing_docs)]
801#[derive(
802 Display,
803 FromStr,
804 Copy,
805 Eq,
806 PartialEq,
807 Debug,
808 JsonSchema,
809 Deserialize,
810 Serialize,
811 Sequence,
812 Clone,
813 Ord,
814 PartialOrd,
815 Default,
816)]
817#[serde(rename_all = "snake_case")]
818#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
819#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
820pub enum PathComponentConstraintType {
821 #[default]
822 Unconstrained,
823 Vertical,
824 Horizontal,
825 EqualLength,
826 Parallel,
827 AngleBetween,
828}
829
830#[allow(missing_docs)]
832#[derive(
833 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
834)]
835#[serde(rename_all = "snake_case")]
836#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
837#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
838pub enum PathCommand {
839 MoveTo,
840 LineTo,
841 BezCurveTo,
842 NurbsCurveTo,
843 AddArc,
844}
845
846#[allow(missing_docs)]
848#[derive(
849 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
850)]
851#[serde(rename_all = "lowercase")]
852#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
853#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
854#[repr(u8)]
855pub enum EntityType {
856 Entity,
857 Object,
858 Path,
859 Curve,
860 Solid2D,
861 Solid3D,
862 Edge,
863 Face,
864 Plane,
865 Vertex,
866}
867
868#[allow(missing_docs)]
870#[derive(
871 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
872)]
873#[serde(rename_all = "snake_case")]
874#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
875#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
876pub enum CurveType {
877 Line,
878 Arc,
879 Nurbs,
880}
881
882#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
884#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
885pub struct ExportFile {
886 pub name: String,
888 pub contents: crate::base64::Base64Data,
890}
891
892#[cfg(feature = "python")]
893#[pyo3_stub_gen::derive::gen_stub_pymethods]
894#[pyo3::pymethods]
895impl ExportFile {
896 #[getter]
897 fn contents(&self) -> Vec<u8> {
898 self.contents.0.clone()
899 }
900
901 #[getter]
902 fn name(&self) -> String {
903 self.name.clone()
904 }
905}
906
907#[derive(
909 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
910)]
911#[serde(rename_all = "lowercase")]
912#[display(style = "lowercase")]
913#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
914#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
915#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
916pub enum FileExportFormat {
917 Fbx,
919 Glb,
926 Gltf,
937 Obj,
941 Ply,
943 Step,
945 Stl,
947}
948
949#[derive(
951 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
952)]
953#[serde(rename_all = "lowercase")]
954#[display(style = "lowercase")]
955#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
956#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
957pub enum FileExportFormat2d {
958 Dxf,
960}
961
962#[derive(
964 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
965)]
966#[serde(rename_all = "lowercase")]
967#[display(style = "lowercase")]
968#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
969#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
970pub enum FileImportFormat {
971 Fbx,
973 Gltf,
975 Obj,
979 Ply,
981 Sldprt,
983 Step,
985 Stl,
987}
988
989#[derive(Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd)]
991#[serde(rename_all = "snake_case")]
992#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
993#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
994pub enum EngineErrorCode {
995 BadRequest = 1,
999 InternalEngine,
1001}
1002
1003impl From<EngineErrorCode> for http::StatusCode {
1004 fn from(e: EngineErrorCode) -> Self {
1005 match e {
1006 EngineErrorCode::BadRequest => Self::BAD_REQUEST,
1007 EngineErrorCode::InternalEngine => Self::INTERNAL_SERVER_ERROR,
1008 }
1009 }
1010}
1011
1012#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1015#[serde(rename_all = "snake_case")]
1016#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1017#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1018pub enum ExtrudeMethod {
1019 New,
1022 #[default]
1025 Merge,
1026}
1027
1028#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1030#[serde(rename_all = "snake_case")]
1031#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1032#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1033pub enum ExtrudeReference {
1034 EntityReference {
1037 entity_id: Uuid,
1039 },
1040 Axis {
1042 axis: Point3d<f64>,
1044 #[serde(default)]
1047 point: Point3d<LengthUnit>,
1048 },
1049 Point {
1051 point: Point3d<LengthUnit>,
1053 },
1054}
1055
1056#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1058#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1059#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1060pub struct ExtrudedFaceInfo {
1061 pub bottom: Option<Uuid>,
1066 pub top: Uuid,
1068 pub sides: Vec<SideFace>,
1070}
1071
1072#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1074#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1075#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1076pub struct SideFace {
1077 pub path_id: Uuid,
1079 pub face_id: Uuid,
1081}
1082
1083#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
1085#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1086#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1087pub struct CameraSettings {
1088 pub pos: Point3d,
1090
1091 pub center: Point3d,
1093
1094 pub up: Point3d,
1096
1097 pub orientation: Quaternion,
1099
1100 pub fov_y: Option<f32>,
1102
1103 pub ortho_scale: Option<f32>,
1105
1106 pub ortho: bool,
1108}
1109
1110#[allow(missing_docs)]
1111#[repr(u8)]
1112#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1113#[serde(rename_all = "snake_case")]
1114#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1115#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1116pub enum WorldCoordinateSystem {
1117 #[default]
1118 RightHandedUpZ,
1119 RightHandedUpY,
1120}
1121
1122#[allow(missing_docs)]
1123#[repr(C)]
1124#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1125#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1126#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1127pub struct CameraViewState {
1128 pub pivot_rotation: Quaternion,
1129 pub pivot_position: Point3d,
1130 pub eye_offset: f32,
1131 pub fov_y: f32,
1132 pub ortho_scale_factor: f32,
1133 pub is_ortho: bool,
1134 pub ortho_scale_enabled: bool,
1135 pub world_coord_system: WorldCoordinateSystem,
1136}
1137
1138impl Default for CameraViewState {
1139 fn default() -> Self {
1140 CameraViewState {
1141 pivot_rotation: Default::default(),
1142 pivot_position: Default::default(),
1143 eye_offset: 10.0,
1144 fov_y: 45.0,
1145 ortho_scale_factor: 1.6,
1146 is_ortho: false,
1147 ortho_scale_enabled: true,
1148 world_coord_system: Default::default(),
1149 }
1150 }
1151}
1152
1153#[cfg(feature = "cxx")]
1154impl_extern_type! {
1155 [Trivial]
1156 CameraViewState = "Endpoints::CameraViewState"
1157}
1158
1159impl From<CameraSettings> for crate::output::DefaultCameraZoom {
1160 fn from(settings: CameraSettings) -> Self {
1161 Self { settings }
1162 }
1163}
1164impl From<CameraSettings> for crate::output::CameraDragMove {
1165 fn from(settings: CameraSettings) -> Self {
1166 Self { settings }
1167 }
1168}
1169impl From<CameraSettings> for crate::output::CameraDragEnd {
1170 fn from(settings: CameraSettings) -> Self {
1171 Self { settings }
1172 }
1173}
1174impl From<CameraSettings> for crate::output::DefaultCameraGetSettings {
1175 fn from(settings: CameraSettings) -> Self {
1176 Self { settings }
1177 }
1178}
1179impl From<CameraSettings> for crate::output::ZoomToFit {
1180 fn from(settings: CameraSettings) -> Self {
1181 Self { settings }
1182 }
1183}
1184impl From<CameraSettings> for crate::output::OrientToFace {
1185 fn from(settings: CameraSettings) -> Self {
1186 Self { settings }
1187 }
1188}
1189impl From<CameraSettings> for crate::output::ViewIsometric {
1190 fn from(settings: CameraSettings) -> Self {
1191 Self { settings }
1192 }
1193}
1194
1195#[derive(Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, PartialOrd, Default)]
1197#[serde(rename_all = "snake_case")]
1198#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1199#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1200pub struct PerspectiveCameraParameters {
1201 pub fov_y: Option<f32>,
1203 pub z_near: Option<f32>,
1205 pub z_far: Option<f32>,
1207}
1208
1209#[derive(
1211 Default,
1212 Display,
1213 FromStr,
1214 Copy,
1215 Eq,
1216 PartialEq,
1217 Debug,
1218 JsonSchema,
1219 Deserialize,
1220 Serialize,
1221 Sequence,
1222 Clone,
1223 Ord,
1224 PartialOrd,
1225)]
1226#[serde(rename_all = "snake_case")]
1227#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1228#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1229pub enum CameraMovement {
1230 #[default]
1232 Vantage,
1233 None,
1235}
1236
1237#[derive(
1239 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1240)]
1241#[serde(rename_all = "lowercase")]
1242#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1243#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1244pub enum GlobalAxis {
1245 X,
1247 Y,
1249 Z,
1251}
1252
1253#[derive(
1255 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1256)]
1257#[serde(rename_all = "snake_case")]
1258#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1259#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1260#[repr(u8)]
1261pub enum ExtrusionFaceCapType {
1262 None,
1264 Top,
1266 Bottom,
1268 Both,
1270}
1271
1272#[allow(missing_docs)]
1274#[derive(
1275 Display,
1276 FromStr,
1277 Copy,
1278 Eq,
1279 PartialEq,
1280 Debug,
1281 JsonSchema,
1282 Deserialize,
1283 Serialize,
1284 Sequence,
1285 Clone,
1286 Ord,
1287 PartialOrd,
1288 Default,
1289)]
1290#[serde(rename_all = "lowercase")]
1291#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1292#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1293pub enum PostEffectType {
1294 Phosphor,
1295 Ssao,
1296 #[default]
1297 NoEffect,
1298}
1299
1300#[cfg(feature = "cxx")]
1303impl_extern_type! {
1304 [Trivial]
1305 FileImportFormat = "Enums::_FileImportFormat"
1307 FileExportFormat = "Enums::_FileExportFormat"
1308 CameraDragInteractionType = "Enums::_CameraDragInteractionType"
1310 SceneSelectionType = "Enums::_SceneSelectionType"
1312 SceneToolType = "Enums::_SceneToolType"
1313 EntityType = "Enums::_EntityType"
1314 AnnotationType = "Enums::_AnnotationType"
1315 AnnotationTextAlignmentX = "Enums::_AnnotationTextAlignmentX"
1316 AnnotationTextAlignmentY = "Enums::_AnnotationTextAlignmentY"
1317 AnnotationLineEnd = "Enums::_AnnotationLineEnd"
1318 MbdStandard = "Enums::_MBDStandard"
1319 MbdSymbol = "Enums::_MBDSymbol"
1320
1321 CurveType = "Enums::_CurveType"
1322 PathCommand = "Enums::_PathCommand"
1323 PathComponentConstraintBound = "Enums::_PathComponentConstraintBound"
1324 PathComponentConstraintType = "Enums::_PathComponentConstraintType"
1325 ExtrusionFaceCapType = "Enums::_ExtrusionFaceCapType"
1326
1327 EngineErrorCode = "Enums::_ErrorCode"
1329 GlobalAxis = "Enums::_GlobalAxis"
1330 OriginType = "Enums::_OriginType"
1331
1332 PostEffectType = "Enums::_PostEffectType"
1334}
1335
1336fn bool_true() -> bool {
1337 true
1338}
1339fn same_scale() -> Point3d<f64> {
1340 Point3d::uniform(1.0)
1341}
1342
1343fn z_axis() -> Point3d<f64> {
1344 Point3d { x: 0.0, y: 0.0, z: 1.0 }
1345}
1346
1347impl ExtrudedFaceInfo {
1348 pub fn list_faces(self) -> Vec<ExtrusionFaceInfo> {
1351 let mut face_infos: Vec<_> = self
1352 .sides
1353 .into_iter()
1354 .map(|side| ExtrusionFaceInfo {
1355 curve_id: Some(side.path_id),
1356 face_id: Some(side.face_id),
1357 cap: ExtrusionFaceCapType::None,
1358 })
1359 .collect();
1360 face_infos.push(ExtrusionFaceInfo {
1361 curve_id: None,
1362 face_id: Some(self.top),
1363 cap: ExtrusionFaceCapType::Top,
1364 });
1365 if let Some(bottom) = self.bottom {
1366 face_infos.push(ExtrusionFaceInfo {
1367 curve_id: None,
1368 face_id: Some(bottom),
1369 cap: ExtrusionFaceCapType::Bottom,
1370 });
1371 }
1372 face_infos
1373 }
1374}
1375
1376#[cfg(test)]
1377mod tests {
1378 use schemars::schema_for;
1379
1380 use super::*;
1381
1382 #[test]
1383 fn check_transformby_deprecated() {
1384 let s = schema_for!(TransformBy<Point3d>);
1385 let pretty = serde_json::to_string_pretty(&s).unwrap();
1386 println!("{pretty}");
1387 let tests: Vec<(OriginType, TransformBy<Point3d>)> = vec![
1388 (
1390 OriginType::Local,
1391 TransformBy {
1392 property: Point3d::default(),
1393 set: true,
1394 #[allow(deprecated)] is_local: true,
1396 origin: None,
1397 },
1398 ),
1399 (
1402 OriginType::Local,
1403 TransformBy {
1404 property: Point3d::default(),
1405 set: true,
1406 #[allow(deprecated)] is_local: false,
1408 origin: Some(OriginType::Local),
1409 },
1410 ),
1411 (
1414 OriginType::Custom {
1415 origin: Point3d::uniform(2.0),
1416 },
1417 TransformBy {
1418 property: Point3d::default(),
1419 set: true,
1420 #[allow(deprecated)] is_local: false,
1422 origin: Some(OriginType::Custom{origin: Point3d::uniform(2.0)}),
1423 },
1424 ),
1425 ];
1426 for (expected, input) in tests {
1427 let actual = input.get_origin();
1428 assert_eq!(actual, expected);
1429 }
1430 }
1431
1432 #[test]
1433 fn test_angle_comparison() {
1434 let a = Angle::from_degrees(90.0);
1435 assert!(a < Angle::from_degrees(91.0));
1436 assert!(a > Angle::from_degrees(89.0));
1437 assert!(a <= Angle::from_degrees(90.0));
1438 assert!(a >= Angle::from_degrees(90.0));
1439 let b = Angle::from_radians(std::f64::consts::FRAC_PI_4);
1440 assert!(b < Angle::from_radians(std::f64::consts::FRAC_PI_2));
1441 assert!(b > Angle::from_radians(std::f64::consts::FRAC_PI_8));
1442 assert!(b <= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1443 assert!(b >= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1444 assert!(a > b);
1446 assert!(a >= b);
1447 assert!(b < a);
1448 assert!(b <= a);
1449 let c = Angle::from_radians(std::f64::consts::FRAC_PI_2 * 3.0);
1450 assert!(a < c);
1451 assert!(a <= c);
1452 assert!(c > a);
1453 assert!(c >= a);
1454 }
1455}
1456
1457#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
1459#[schemars(rename = "TransformByFor{T}")]
1460#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1461#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1462pub struct TransformBy<T> {
1463 pub property: T,
1465 pub set: bool,
1470 #[deprecated(note = "Use the `origin` field instead.")]
1473 pub is_local: bool,
1474 #[serde(default)]
1478 pub origin: Option<OriginType>,
1479}
1480
1481impl<T> TransformBy<T> {
1482 pub fn get_origin(&self) -> OriginType {
1486 if let Some(origin) = self.origin {
1487 return origin;
1488 }
1489 #[expect(
1490 deprecated,
1491 reason = "Must fall back to the deprecated field if the API client isn't using the new field yet."
1492 )]
1493 if self.is_local {
1494 OriginType::Local
1495 } else {
1496 OriginType::Global
1497 }
1498 }
1499}
1500
1501#[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, Default)]
1504#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1505#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1506pub struct ComponentTransform {
1507 pub translate: Option<TransformBy<Point3d<LengthUnit>>>,
1509 pub rotate_rpy: Option<TransformBy<Point3d<f64>>>,
1512 pub rotate_angle_axis: Option<TransformBy<Point4d<f64>>>,
1516 pub scale: Option<TransformBy<Point3d<f64>>>,
1518}
1519
1520#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
1523#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1524#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1525pub enum Opposite<T> {
1526 #[default]
1528 None,
1529 Symmetric,
1531 Other(T),
1533}
1534
1535impl<T: JsonSchema> JsonSchema for Opposite<T> {
1536 fn schema_name() -> String {
1537 format!("OppositeFor{}", T::schema_name())
1538 }
1539
1540 fn schema_id() -> std::borrow::Cow<'static, str> {
1541 std::borrow::Cow::Owned(format!("{}::Opposite<{}>", module_path!(), T::schema_id()))
1542 }
1543
1544 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1545 SchemaObject {
1546 instance_type: Some(schemars::schema::InstanceType::String.into()),
1547 ..Default::default()
1548 }
1549 .into()
1550 }
1551}
1552
1553#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1556#[serde(rename_all = "snake_case")]
1557#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1558#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1559pub enum CutStrategy {
1560 Basic,
1563 Csg,
1566 #[default]
1568 Automatic,
1569}
1570
1571#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1573#[serde(rename_all = "snake_case")]
1574#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1575#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1576pub enum RelativeTo {
1577 #[default]
1579 SketchPlane,
1580 TrajectoryCurve,
1582}