1use crate::def_enum::negative_one;
2use enum_iterator::Sequence;
3use parse_display_derive::{Display, FromStr};
4pub use point::{Point2d, Point3d, Point4d, Quaternion};
5use schemars::{schema::SchemaObject, JsonSchema};
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9#[cfg(feature = "cxx")]
10use crate::impl_extern_type;
11use crate::{length_unit::LengthUnit, output::ExtrusionFaceInfo, units::UnitAngle};
12
13mod point;
14
15#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
17#[serde(rename_all = "snake_case")]
18#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
19#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
20pub enum CutType {
21 #[default]
23 Fillet,
24 Chamfer,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
30#[serde(rename_all = "snake_case")]
31#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
32#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
33pub enum CutTypeV2 {
34 Fillet {
36 radius: LengthUnit,
38 second_length: Option<LengthUnit>,
41 },
42 Chamfer {
44 distance: LengthUnit,
46 second_distance: Option<LengthUnit>,
48 angle: Option<Angle>,
50 swap: bool,
52 },
53 Custom {
55 path: Uuid,
57 },
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
62#[serde(rename_all = "snake_case")]
63#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
64#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
65pub struct Rotation {
66 pub axis: Point3d<f64>,
69 pub angle: Angle,
72 pub origin: OriginType,
74}
75
76impl Default for Rotation {
77 fn default() -> Self {
79 Self {
80 axis: z_axis(),
81 angle: Angle::default(),
82 origin: OriginType::Local,
83 }
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
89#[serde(rename_all = "snake_case")]
90#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
91#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
92pub struct Transform {
93 #[serde(default)]
96 pub translate: Point3d<LengthUnit>,
97 #[serde(default = "same_scale")]
100 pub scale: Point3d<f64>,
101 #[serde(default)]
104 pub rotation: Rotation,
105 #[serde(default = "bool_true")]
107 pub replicate: bool,
108}
109
110impl Default for Transform {
111 fn default() -> Self {
112 Self {
113 scale: same_scale(),
114 replicate: true,
115 translate: Default::default(),
116 rotation: Rotation::default(),
117 }
118 }
119}
120
121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
123#[serde(rename_all = "snake_case")]
124#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
125#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
126pub struct AnnotationOptions {
127 pub text: Option<AnnotationTextOptions>,
129 pub line_ends: Option<AnnotationLineEndOptions>,
131 pub line_width: Option<f32>,
133 pub color: Option<Color>,
135 pub position: Option<Point3d<f32>>,
137 pub dimension: Option<AnnotationBasicDimension>,
139 pub feature_control: Option<AnnotationFeatureControl>,
141 pub feature_tag: Option<AnnotationFeatureTag>,
143}
144
145#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
147#[serde(rename_all = "snake_case")]
148#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
149#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
150pub struct AnnotationLineEndOptions {
151 pub start: AnnotationLineEnd,
153 pub end: AnnotationLineEnd,
155}
156
157#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
159#[serde(rename_all = "snake_case")]
160#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
161#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
162pub struct AnnotationTextOptions {
163 pub x: AnnotationTextAlignmentX,
165 pub y: AnnotationTextAlignmentY,
167 pub text: String,
169 pub point_size: u32,
171}
172
173#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
175#[serde(rename_all = "snake_case")]
176#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
177#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
178pub struct AnnotationMbdControlFrame {
179 pub symbol: MbdSymbol,
181 pub diameter_symbol: Option<MbdSymbol>,
183 pub tolerance: f64,
185 pub modifier: Option<MbdSymbol>,
187 pub primary_datum: Option<char>,
189 pub secondary_datum: Option<char>,
191 pub tertiary_datum: Option<char>,
193}
194
195#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
197#[serde(rename_all = "snake_case")]
198#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
199#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
200pub struct AnnotationMbdBasicDimension {
201 pub symbol: Option<MbdSymbol>,
203 pub dimension: Option<f64>,
205 pub tolerance: f64,
207}
208
209#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
211#[serde(rename_all = "snake_case")]
212#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
213#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
214pub struct AnnotationBasicDimension {
215 pub from_entity_id: Uuid,
217
218 pub from_entity_pos: Point2d<f64>,
220
221 pub to_entity_id: Uuid,
223
224 pub to_entity_pos: Point2d<f64>,
226
227 pub dimension: AnnotationMbdBasicDimension,
229
230 pub plane_id: Uuid,
232
233 pub offset: Point2d<f64>,
235
236 pub precision: u32,
238
239 pub font_scale: f32,
241
242 pub font_point_size: u32,
244
245 #[serde(default = "one")]
247 pub arrow_scale: f32,
248}
249
250#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
252#[serde(rename_all = "snake_case")]
253#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
254#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
255pub struct AnnotationFeatureControl {
256 pub entity_id: Uuid,
258
259 pub entity_pos: Point2d<f64>,
261
262 pub leader_type: AnnotationLineEnd,
264
265 pub dimension: Option<AnnotationMbdBasicDimension>,
267
268 pub control_frame: Option<AnnotationMbdControlFrame>,
270
271 pub defined_datum: Option<char>,
273
274 pub prefix: Option<String>,
276
277 pub suffix: Option<String>,
279
280 pub plane_id: Uuid,
282
283 pub offset: Point2d<f64>,
285
286 pub precision: u32,
288
289 pub font_scale: f32,
291
292 pub font_point_size: u32,
294
295 #[serde(default = "one")]
297 pub leader_scale: f32,
298}
299
300#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
302#[serde(rename_all = "snake_case")]
303#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
304#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
305pub struct AnnotationFeatureTag {
306 pub entity_id: Uuid,
308
309 pub entity_pos: Point2d<f64>,
311
312 pub leader_type: AnnotationLineEnd,
314
315 pub key: String,
317
318 pub value: String,
320
321 pub show_key: bool,
323
324 pub plane_id: Uuid,
326
327 pub offset: Point2d<f64>,
329
330 pub font_scale: f32,
332
333 pub font_point_size: u32,
335
336 #[serde(default = "one")]
338 pub leader_scale: f32,
339}
340
341#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
345#[serde(rename_all = "snake_case", tag = "type")]
346#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
347#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
348pub enum DistanceType {
349 Euclidean {},
351 OnAxis {
353 axis: GlobalAxis,
355 },
356}
357
358#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
360#[serde(rename_all = "snake_case", tag = "type")]
361#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
362#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
363pub enum OriginType {
364 #[default]
366 Local,
367 Global,
369 Custom {
371 origin: Point3d<f64>,
373 },
374}
375
376#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
378#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
379#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
380pub struct Color {
381 pub r: f32,
383 pub g: f32,
385 pub b: f32,
387 pub a: f32,
389}
390
391#[allow(missing_docs)]
393#[derive(
394 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
395)]
396#[serde(rename_all = "lowercase")]
397#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
398#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
399pub enum AnnotationTextAlignmentX {
400 Left,
401 Center,
402 Right,
403}
404
405#[allow(missing_docs)]
407#[derive(
408 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
409)]
410#[serde(rename_all = "lowercase")]
411#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
412#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
413pub enum AnnotationTextAlignmentY {
414 Bottom,
415 Center,
416 Top,
417}
418
419#[allow(missing_docs)]
421#[derive(
422 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
423)]
424#[serde(rename_all = "lowercase")]
425#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
426#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
427pub enum AnnotationLineEnd {
428 None,
429 Arrow,
430 Dot,
431}
432
433#[derive(
435 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
436)]
437#[serde(rename_all = "lowercase")]
438#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
439#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
440pub enum AnnotationType {
441 T2D,
443 T3D,
445}
446
447#[derive(
449 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
450)]
451#[serde(rename_all = "lowercase")]
452#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
453#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
454pub enum MbdStandard {
455 AsmeY14_5,
457}
458
459#[allow(missing_docs)]
462#[derive(
463 Default,
464 Display,
465 FromStr,
466 Copy,
467 Eq,
468 PartialEq,
469 Debug,
470 JsonSchema,
471 Deserialize,
472 Serialize,
473 Sequence,
474 Clone,
475 Ord,
476 PartialOrd,
477)]
478#[serde(rename_all = "lowercase")]
479#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
480#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
481#[repr(u16)]
482pub enum MbdSymbol {
483 #[default]
484 None = 0,
485 ArcLength = 174,
486 Between = 175,
487 Degrees = 176,
488 PlusMinus = 177,
489 Angularity = 178,
490 Cylindricity = 179,
491 Roundness = 180,
492 Concentricity = 181,
493 Straightness = 182,
494 Parallelism = 183,
495 Flatness = 184,
496 ProfileOfLine = 185,
497 SurfaceProfile = 186,
498 Symmetry = 187,
499 Perpendicularity = 188,
500 Runout = 189,
501 TotalRunout = 190,
502 Position = 191,
503 CenterLine = 192,
504 PartingLine = 193,
505 IsoEnvelope = 195,
506 IsoEnvelopeNonY145M = 196,
507 FreeState = 197,
508 StatisticalTolerance = 198,
509 ContinuousFeature = 199,
510 Independency = 200,
511 Depth = 201,
512 Start = 202,
513 LeastCondition = 203,
514 MaxCondition = 204,
515 ConicalTaper = 205,
516 Projected = 206,
517 Slope = 207,
518 Micro = 208,
519 TangentPlane = 210,
520 Unilateral = 211,
521 SquareFeature = 212,
522 Countersink = 213,
523 SpotFace = 214,
524 Target = 215,
525 Diameter = 216,
526 Radius = 217,
527 SphericalRadius = 218,
528 SphericalDiameter = 219,
529 ControlledRadius = 220,
530 BoxStart = 123,
531 BoxBar = 162,
532 BoxBarBetween = 124,
533 LetterBackwardUnderline = 95,
534 PunctuationBackwardUnderline = 92,
535 ModifierBackwardUnderline = 126,
536 NumericBackwardUnderline = 96,
537 BoxEnd = 125,
538 DatumUp = 166,
539 DatumLeft = 168,
540 DatumRight = 167,
541 DatumDown = 165,
542 DatumTriangle = 295,
543 HalfSpace = 236,
544 QuarterSpace = 237,
545 EighthSpace = 238,
546 ModifierSpace = 239,
547}
548
549#[derive(
551 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
552)]
553#[serde(rename_all = "lowercase")]
554#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
555#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
556pub enum CameraDragInteractionType {
557 Pan,
559 Rotate,
561 RotateTrackball,
563 Zoom,
565}
566
567#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
570#[serde(rename_all = "snake_case", tag = "type")]
571#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
572#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
573pub enum PathSegment {
574 Line {
577 end: Point3d<LengthUnit>,
579 relative: bool,
581 },
582 Arc {
585 center: Point2d<LengthUnit>,
587 radius: LengthUnit,
589 start: Angle,
591 end: Angle,
593 relative: bool,
595 },
596 Bezier {
600 control1: Point3d<LengthUnit>,
602 control2: Point3d<LengthUnit>,
604 end: Point3d<LengthUnit>,
606 relative: bool,
608 },
609 TangentialArc {
611 radius: LengthUnit,
614 offset: Angle,
616 },
617 TangentialArcTo {
620 to: Point3d<LengthUnit>,
624 angle_snap_increment: Option<Angle>,
626 },
627 ArcTo {
629 interior: Point3d<LengthUnit>,
631 end: Point3d<LengthUnit>,
633 relative: bool,
635 },
636 CircularInvolute {
639 start_radius: LengthUnit,
642 end_radius: LengthUnit,
645 angle: Angle,
648 reverse: bool,
651 },
652 Ellipse {
654 center: Point2d<LengthUnit>,
656 major_axis: Point2d<LengthUnit>,
658 minor_radius: LengthUnit,
660 start_angle: Angle,
662 end_angle: Angle,
664 },
665 ConicTo {
668 interior: Point2d<LengthUnit>,
670 end: Point2d<LengthUnit>,
672 start_tangent: Point2d<LengthUnit>,
674 end_tangent: Point2d<LengthUnit>,
676 relative: bool,
678 },
679}
680
681#[derive(Clone, Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
683#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
684#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
685pub struct Angle {
686 pub unit: UnitAngle,
688 pub value: f64,
690}
691
692impl Angle {
693 pub fn to_degrees(self) -> f64 {
695 match self.unit {
696 UnitAngle::Degrees => self.value,
697 UnitAngle::Radians => self.value.to_degrees(),
698 }
699 }
700 pub fn to_radians(self) -> f64 {
702 match self.unit {
703 UnitAngle::Degrees => self.value.to_radians(),
704 UnitAngle::Radians => self.value,
705 }
706 }
707 pub const fn from_degrees(value: f64) -> Self {
709 Self {
710 unit: UnitAngle::Degrees,
711 value,
712 }
713 }
714 pub const fn from_radians(value: f64) -> Self {
716 Self {
717 unit: UnitAngle::Radians,
718 value,
719 }
720 }
721 pub const fn turn() -> Self {
723 Self::from_degrees(360.0)
724 }
725 pub const fn half_circle() -> Self {
727 Self::from_degrees(180.0)
728 }
729 pub const fn quarter_circle() -> Self {
731 Self::from_degrees(90.0)
732 }
733 pub const fn zero() -> Self {
735 Self::from_degrees(0.0)
736 }
737}
738
739impl Default for Angle {
741 fn default() -> Self {
743 Self::zero()
744 }
745}
746
747impl PartialOrd for Angle {
748 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
749 match (self.unit, other.unit) {
750 (UnitAngle::Degrees, UnitAngle::Degrees) => self.value.partial_cmp(&other.value),
752 (UnitAngle::Radians, UnitAngle::Radians) => self.value.partial_cmp(&other.value),
753 _ => self.to_degrees().partial_cmp(&other.to_degrees()),
754 }
755 }
756}
757
758impl std::ops::Add for Angle {
759 type Output = Self;
760
761 fn add(self, rhs: Self) -> Self::Output {
762 Self {
763 unit: UnitAngle::Degrees,
764 value: self.to_degrees() + rhs.to_degrees(),
765 }
766 }
767}
768
769impl std::ops::AddAssign for Angle {
770 fn add_assign(&mut self, rhs: Self) {
771 match self.unit {
772 UnitAngle::Degrees => {
773 self.value += rhs.to_degrees();
774 }
775 UnitAngle::Radians => {
776 self.value += rhs.to_radians();
777 }
778 }
779 }
780}
781
782#[derive(
784 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
785)]
786#[serde(rename_all = "lowercase")]
787#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
788#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
789pub enum SceneSelectionType {
790 Replace,
792 Add,
794 Remove,
796}
797
798#[allow(missing_docs)]
800#[derive(
801 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
802)]
803#[serde(rename_all = "snake_case")]
804#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
805#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
806pub enum SceneToolType {
807 CameraRevolve,
808 Select,
809 Move,
810 SketchLine,
811 SketchTangentialArc,
812 SketchCurve,
813 SketchCurveMod,
814}
815
816#[allow(missing_docs)]
818#[derive(
819 Display,
820 FromStr,
821 Copy,
822 Eq,
823 PartialEq,
824 Debug,
825 JsonSchema,
826 Deserialize,
827 Serialize,
828 Sequence,
829 Clone,
830 Ord,
831 PartialOrd,
832 Default,
833)]
834#[serde(rename_all = "snake_case")]
835#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
836#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
837pub enum PathComponentConstraintBound {
838 #[default]
839 Unconstrained,
840 PartiallyConstrained,
841 FullyConstrained,
842}
843
844#[allow(missing_docs)]
846#[derive(
847 Display,
848 FromStr,
849 Copy,
850 Eq,
851 PartialEq,
852 Debug,
853 JsonSchema,
854 Deserialize,
855 Serialize,
856 Sequence,
857 Clone,
858 Ord,
859 PartialOrd,
860 Default,
861)]
862#[serde(rename_all = "snake_case")]
863#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
864#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
865pub enum PathComponentConstraintType {
866 #[default]
867 Unconstrained,
868 Vertical,
869 Horizontal,
870 EqualLength,
871 Parallel,
872 AngleBetween,
873}
874
875#[allow(missing_docs)]
877#[derive(
878 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
879)]
880#[serde(rename_all = "snake_case")]
881#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
882#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
883pub enum PathCommand {
884 MoveTo,
885 LineTo,
886 BezCurveTo,
887 NurbsCurveTo,
888 AddArc,
889}
890
891#[allow(missing_docs)]
893#[derive(
894 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
895)]
896#[serde(rename_all = "lowercase")]
897#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
898#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
899#[repr(u8)]
900pub enum EntityType {
901 Entity,
902 Object,
903 Path,
904 Curve,
905 Solid2D,
906 Solid3D,
907 Edge,
908 Face,
909 Plane,
910 Vertex,
911}
912
913#[allow(missing_docs)]
915#[derive(
916 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
917)]
918#[serde(rename_all = "snake_case")]
919#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
920#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
921pub enum CurveType {
922 Line,
923 Arc,
924 Nurbs,
925}
926
927#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
929#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
930pub struct ExportFile {
931 pub name: String,
933 pub contents: crate::base64::Base64Data,
935}
936
937#[cfg(feature = "python")]
938#[pyo3_stub_gen::derive::gen_stub_pymethods]
939#[pyo3::pymethods]
940impl ExportFile {
941 #[getter]
942 fn contents(&self) -> Vec<u8> {
943 self.contents.0.clone()
944 }
945
946 #[getter]
947 fn name(&self) -> String {
948 self.name.clone()
949 }
950}
951
952#[derive(
954 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
955)]
956#[serde(rename_all = "lowercase")]
957#[display(style = "lowercase")]
958#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
959#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
960#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
961pub enum FileExportFormat {
962 Fbx,
964 Glb,
971 Gltf,
982 Obj,
986 Ply,
988 Step,
990 Stl,
992}
993
994#[derive(
996 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
997)]
998#[serde(rename_all = "lowercase")]
999#[display(style = "lowercase")]
1000#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1001#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1002pub enum FileExportFormat2d {
1003 Dxf,
1005}
1006
1007#[derive(
1009 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
1010)]
1011#[serde(rename_all = "lowercase")]
1012#[display(style = "lowercase")]
1013#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1014#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1015pub enum FileImportFormat {
1016 Fbx,
1018 Gltf,
1020 Obj,
1024 Ply,
1026 Sldprt,
1028 Step,
1030 Stl,
1032}
1033
1034#[derive(Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd)]
1036#[serde(rename_all = "snake_case")]
1037#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1038#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1039pub enum EngineErrorCode {
1040 BadRequest = 1,
1044 InternalEngine,
1046}
1047
1048impl From<EngineErrorCode> for http::StatusCode {
1049 fn from(e: EngineErrorCode) -> Self {
1050 match e {
1051 EngineErrorCode::BadRequest => Self::BAD_REQUEST,
1052 EngineErrorCode::InternalEngine => Self::INTERNAL_SERVER_ERROR,
1053 }
1054 }
1055}
1056
1057#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1059#[serde(rename_all = "snake_case")]
1060#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1061#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1062pub enum BodyType {
1063 #[default]
1065 Solid,
1066 Surface,
1068}
1069
1070#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1073#[serde(rename_all = "snake_case")]
1074#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1075#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1076pub enum ExtrudeMethod {
1077 New,
1080 #[default]
1083 Merge,
1084}
1085
1086#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1088#[serde(rename_all = "snake_case")]
1089#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1090#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1091pub enum ExtrudeReference {
1092 EntityReference {
1095 entity_id: Uuid,
1097 },
1098 Axis {
1100 axis: Point3d<f64>,
1102 #[serde(default)]
1105 point: Point3d<LengthUnit>,
1106 },
1107 Point {
1109 point: Point3d<LengthUnit>,
1111 },
1112}
1113
1114#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1116#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1117#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1118pub struct ExtrudedFaceInfo {
1119 pub bottom: Option<Uuid>,
1124 pub top: Uuid,
1126 pub sides: Vec<SideFace>,
1128}
1129
1130#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1132#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1133#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1134pub struct SideFace {
1135 pub path_id: Uuid,
1137 pub face_id: Uuid,
1139}
1140
1141#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
1143#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1144#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1145pub struct CameraSettings {
1146 pub pos: Point3d,
1148
1149 pub center: Point3d,
1151
1152 pub up: Point3d,
1154
1155 pub orientation: Quaternion,
1157
1158 pub fov_y: Option<f32>,
1160
1161 pub ortho_scale: Option<f32>,
1163
1164 pub ortho: bool,
1166}
1167
1168#[allow(missing_docs)]
1169#[repr(u8)]
1170#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1171#[serde(rename_all = "snake_case")]
1172#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1173#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1174pub enum WorldCoordinateSystem {
1175 #[default]
1176 RightHandedUpZ,
1177 RightHandedUpY,
1178}
1179
1180#[allow(missing_docs)]
1181#[repr(C)]
1182#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1183#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1184#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1185pub struct CameraViewState {
1186 pub pivot_rotation: Quaternion,
1187 pub pivot_position: Point3d,
1188 pub eye_offset: f32,
1189 pub fov_y: f32,
1190 pub ortho_scale_factor: f32,
1191 pub is_ortho: bool,
1192 pub ortho_scale_enabled: bool,
1193 pub world_coord_system: WorldCoordinateSystem,
1194}
1195
1196impl Default for CameraViewState {
1197 fn default() -> Self {
1198 CameraViewState {
1199 pivot_rotation: Default::default(),
1200 pivot_position: Default::default(),
1201 eye_offset: 10.0,
1202 fov_y: 45.0,
1203 ortho_scale_factor: 1.6,
1204 is_ortho: false,
1205 ortho_scale_enabled: true,
1206 world_coord_system: Default::default(),
1207 }
1208 }
1209}
1210
1211#[cfg(feature = "cxx")]
1212impl_extern_type! {
1213 [Trivial]
1214 CameraViewState = "Endpoints::CameraViewState"
1215}
1216
1217impl From<CameraSettings> for crate::output::DefaultCameraZoom {
1218 fn from(settings: CameraSettings) -> Self {
1219 Self { settings }
1220 }
1221}
1222impl From<CameraSettings> for crate::output::CameraDragMove {
1223 fn from(settings: CameraSettings) -> Self {
1224 Self { settings }
1225 }
1226}
1227impl From<CameraSettings> for crate::output::CameraDragEnd {
1228 fn from(settings: CameraSettings) -> Self {
1229 Self { settings }
1230 }
1231}
1232impl From<CameraSettings> for crate::output::DefaultCameraGetSettings {
1233 fn from(settings: CameraSettings) -> Self {
1234 Self { settings }
1235 }
1236}
1237impl From<CameraSettings> for crate::output::ZoomToFit {
1238 fn from(settings: CameraSettings) -> Self {
1239 Self { settings }
1240 }
1241}
1242impl From<CameraSettings> for crate::output::OrientToFace {
1243 fn from(settings: CameraSettings) -> Self {
1244 Self { settings }
1245 }
1246}
1247impl From<CameraSettings> for crate::output::ViewIsometric {
1248 fn from(settings: CameraSettings) -> Self {
1249 Self { settings }
1250 }
1251}
1252
1253#[derive(Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, PartialOrd, Default)]
1255#[serde(rename_all = "snake_case")]
1256#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1257#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1258pub struct PerspectiveCameraParameters {
1259 pub fov_y: Option<f32>,
1261 pub z_near: Option<f32>,
1263 pub z_far: Option<f32>,
1265}
1266
1267#[derive(
1269 Default,
1270 Display,
1271 FromStr,
1272 Copy,
1273 Eq,
1274 PartialEq,
1275 Debug,
1276 JsonSchema,
1277 Deserialize,
1278 Serialize,
1279 Sequence,
1280 Clone,
1281 Ord,
1282 PartialOrd,
1283)]
1284#[serde(rename_all = "snake_case")]
1285#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1286#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1287pub enum CameraMovement {
1288 #[default]
1290 Vantage,
1291 None,
1293}
1294
1295#[derive(
1297 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1298)]
1299#[serde(rename_all = "lowercase")]
1300#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1301#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1302pub enum GlobalAxis {
1303 X,
1305 Y,
1307 Z,
1309}
1310
1311#[derive(
1313 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1314)]
1315#[serde(rename_all = "snake_case")]
1316#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1317#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1318#[repr(u8)]
1319pub enum ExtrusionFaceCapType {
1320 None,
1322 Top,
1324 Bottom,
1326 Both,
1328}
1329
1330#[allow(missing_docs)]
1332#[derive(
1333 Display,
1334 FromStr,
1335 Copy,
1336 Eq,
1337 PartialEq,
1338 Debug,
1339 JsonSchema,
1340 Deserialize,
1341 Serialize,
1342 Sequence,
1343 Clone,
1344 Ord,
1345 PartialOrd,
1346 Default,
1347)]
1348#[serde(rename_all = "lowercase")]
1349#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1350#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1351pub enum PostEffectType {
1352 Phosphor,
1353 Ssao,
1354 #[default]
1355 NoEffect,
1356}
1357
1358#[cfg(feature = "cxx")]
1361impl_extern_type! {
1362 [Trivial]
1363 FileImportFormat = "Enums::_FileImportFormat"
1365 FileExportFormat = "Enums::_FileExportFormat"
1366 CameraDragInteractionType = "Enums::_CameraDragInteractionType"
1368 SceneSelectionType = "Enums::_SceneSelectionType"
1370 SceneToolType = "Enums::_SceneToolType"
1371 BodyType = "Enums::_BodyType"
1372 EntityType = "Enums::_EntityType"
1373 AnnotationType = "Enums::_AnnotationType"
1374 AnnotationTextAlignmentX = "Enums::_AnnotationTextAlignmentX"
1375 AnnotationTextAlignmentY = "Enums::_AnnotationTextAlignmentY"
1376 AnnotationLineEnd = "Enums::_AnnotationLineEnd"
1377 MbdStandard = "Enums::_MBDStandard"
1378 MbdSymbol = "Enums::_MBDSymbol"
1379
1380 CurveType = "Enums::_CurveType"
1381 PathCommand = "Enums::_PathCommand"
1382 PathComponentConstraintBound = "Enums::_PathComponentConstraintBound"
1383 PathComponentConstraintType = "Enums::_PathComponentConstraintType"
1384 ExtrusionFaceCapType = "Enums::_ExtrusionFaceCapType"
1385
1386 EngineErrorCode = "Enums::_ErrorCode"
1388 GlobalAxis = "Enums::_GlobalAxis"
1389 OriginType = "Enums::_OriginType"
1390
1391 PostEffectType = "Enums::_PostEffectType"
1393}
1394
1395fn bool_true() -> bool {
1396 true
1397}
1398fn same_scale() -> Point3d<f64> {
1399 Point3d::uniform(1.0)
1400}
1401
1402fn z_axis() -> Point3d<f64> {
1403 Point3d { x: 0.0, y: 0.0, z: 1.0 }
1404}
1405
1406impl ExtrudedFaceInfo {
1407 pub fn list_faces(self) -> Vec<ExtrusionFaceInfo> {
1410 let mut face_infos: Vec<_> = self
1411 .sides
1412 .into_iter()
1413 .map(|side| ExtrusionFaceInfo {
1414 curve_id: Some(side.path_id),
1415 face_id: Some(side.face_id),
1416 cap: ExtrusionFaceCapType::None,
1417 })
1418 .collect();
1419 face_infos.push(ExtrusionFaceInfo {
1420 curve_id: None,
1421 face_id: Some(self.top),
1422 cap: ExtrusionFaceCapType::Top,
1423 });
1424 if let Some(bottom) = self.bottom {
1425 face_infos.push(ExtrusionFaceInfo {
1426 curve_id: None,
1427 face_id: Some(bottom),
1428 cap: ExtrusionFaceCapType::Bottom,
1429 });
1430 }
1431 face_infos
1432 }
1433}
1434
1435#[cfg(test)]
1436mod tests {
1437 use schemars::schema_for;
1438
1439 use super::*;
1440
1441 #[test]
1442 fn check_transformby_deprecated() {
1443 let s = schema_for!(TransformBy<Point3d>);
1444 let pretty = serde_json::to_string_pretty(&s).unwrap();
1445 println!("{pretty}");
1446 let tests: Vec<(OriginType, TransformBy<Point3d>)> = vec![
1447 (
1449 OriginType::Local,
1450 TransformBy {
1451 property: Point3d::default(),
1452 set: true,
1453 #[allow(deprecated)] is_local: true,
1455 origin: None,
1456 },
1457 ),
1458 (
1461 OriginType::Local,
1462 TransformBy {
1463 property: Point3d::default(),
1464 set: true,
1465 #[allow(deprecated)] is_local: false,
1467 origin: Some(OriginType::Local),
1468 },
1469 ),
1470 (
1473 OriginType::Custom {
1474 origin: Point3d::uniform(2.0),
1475 },
1476 TransformBy {
1477 property: Point3d::default(),
1478 set: true,
1479 #[allow(deprecated)] is_local: false,
1481 origin: Some(OriginType::Custom{origin: Point3d::uniform(2.0)}),
1482 },
1483 ),
1484 ];
1485 for (expected, input) in tests {
1486 let actual = input.get_origin();
1487 assert_eq!(actual, expected);
1488 }
1489 }
1490
1491 #[test]
1492 fn test_angle_comparison() {
1493 let a = Angle::from_degrees(90.0);
1494 assert!(a < Angle::from_degrees(91.0));
1495 assert!(a > Angle::from_degrees(89.0));
1496 assert!(a <= Angle::from_degrees(90.0));
1497 assert!(a >= Angle::from_degrees(90.0));
1498 let b = Angle::from_radians(std::f64::consts::FRAC_PI_4);
1499 assert!(b < Angle::from_radians(std::f64::consts::FRAC_PI_2));
1500 assert!(b > Angle::from_radians(std::f64::consts::FRAC_PI_8));
1501 assert!(b <= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1502 assert!(b >= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1503 assert!(a > b);
1505 assert!(a >= b);
1506 assert!(b < a);
1507 assert!(b <= a);
1508 let c = Angle::from_radians(std::f64::consts::FRAC_PI_2 * 3.0);
1509 assert!(a < c);
1510 assert!(a <= c);
1511 assert!(c > a);
1512 assert!(c >= a);
1513 }
1514}
1515
1516#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
1518#[schemars(rename = "TransformByFor{T}")]
1519#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1520#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1521pub struct TransformBy<T> {
1522 pub property: T,
1524 pub set: bool,
1529 #[deprecated(note = "Use the `origin` field instead.")]
1532 pub is_local: bool,
1533 #[serde(default)]
1537 pub origin: Option<OriginType>,
1538}
1539
1540impl<T> TransformBy<T> {
1541 pub fn get_origin(&self) -> OriginType {
1545 if let Some(origin) = self.origin {
1546 return origin;
1547 }
1548 #[expect(
1549 deprecated,
1550 reason = "Must fall back to the deprecated field if the API client isn't using the new field yet."
1551 )]
1552 if self.is_local {
1553 OriginType::Local
1554 } else {
1555 OriginType::Global
1556 }
1557 }
1558}
1559
1560#[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, Default)]
1563#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1564#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1565pub struct ComponentTransform {
1566 pub translate: Option<TransformBy<Point3d<LengthUnit>>>,
1568 pub rotate_rpy: Option<TransformBy<Point3d<f64>>>,
1571 pub rotate_angle_axis: Option<TransformBy<Point4d<f64>>>,
1575 pub scale: Option<TransformBy<Point3d<f64>>>,
1577}
1578
1579#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
1582#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1583#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1584pub enum Opposite<T> {
1585 #[default]
1587 None,
1588 Symmetric,
1590 Other(T),
1592}
1593
1594impl<T: JsonSchema> JsonSchema for Opposite<T> {
1595 fn schema_name() -> String {
1596 format!("OppositeFor{}", T::schema_name())
1597 }
1598
1599 fn schema_id() -> std::borrow::Cow<'static, str> {
1600 std::borrow::Cow::Owned(format!("{}::Opposite<{}>", module_path!(), T::schema_id()))
1601 }
1602
1603 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1604 SchemaObject {
1605 instance_type: Some(schemars::schema::InstanceType::String.into()),
1606 ..Default::default()
1607 }
1608 .into()
1609 }
1610}
1611
1612#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1615#[serde(rename_all = "snake_case")]
1616#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1617#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1618pub enum CutStrategy {
1619 Basic,
1622 Csg,
1625 #[default]
1627 Automatic,
1628}
1629
1630#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1632#[serde(rename_all = "snake_case")]
1633#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1634#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1635pub enum RelativeTo {
1636 #[default]
1638 SketchPlane,
1639 TrajectoryCurve,
1641}
1642
1643#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
1645#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1646#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1647pub struct SelectedRegion {
1648 pub segment: Uuid,
1650 pub intersection_segment: Uuid,
1653 #[serde(default = "negative_one")]
1657 pub intersection_index: i32,
1658 #[serde(default)]
1661 pub curve_clockwise: bool,
1662}
1663
1664impl Default for SelectedRegion {
1665 fn default() -> Self {
1666 Self {
1667 segment: Default::default(),
1668 intersection_segment: Default::default(),
1669 intersection_index: -1,
1670 curve_clockwise: Default::default(),
1671 }
1672 }
1673}
1674
1675fn one() -> f32 {
1676 1.0
1677}