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, Copy, 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 enum CutTypeV2 {
33 Fillet {
35 radius: LengthUnit,
37 second_length: Option<LengthUnit>,
40 },
41 Chamfer {
43 distance: LengthUnit,
45 second_distance: Option<LengthUnit>,
47 angle: Option<Angle>,
49 swap: bool,
51 },
52 Custom {
54 path: Uuid,
56 },
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
61#[serde(rename_all = "snake_case")]
62#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
63#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
64pub struct Rotation {
65 pub axis: Point3d<f64>,
68 pub angle: Angle,
71 pub origin: OriginType,
73}
74
75impl Default for Rotation {
76 fn default() -> Self {
78 Self {
79 axis: z_axis(),
80 angle: Angle::default(),
81 origin: OriginType::Local,
82 }
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
88#[serde(rename_all = "snake_case")]
89#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
90#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
91pub struct Transform {
92 #[serde(default)]
95 pub translate: Point3d<LengthUnit>,
96 #[serde(default = "same_scale")]
99 pub scale: Point3d<f64>,
100 #[serde(default)]
103 pub rotation: Rotation,
104 #[serde(default = "bool_true")]
106 pub replicate: bool,
107}
108
109impl Default for Transform {
110 fn default() -> Self {
111 Self {
112 scale: same_scale(),
113 replicate: true,
114 translate: Default::default(),
115 rotation: Rotation::default(),
116 }
117 }
118}
119
120#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
122#[serde(rename_all = "snake_case")]
123#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
124#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
125pub struct AnnotationOptions {
126 pub text: Option<AnnotationTextOptions>,
128 pub line_ends: Option<AnnotationLineEndOptions>,
130 pub line_width: Option<f32>,
132 pub color: Option<Color>,
134 pub position: Option<Point3d<f32>>,
136 pub dimension: Option<AnnotationBasicDimension>,
138 pub feature_control: Option<AnnotationFeatureControl>,
140 pub feature_tag: Option<AnnotationFeatureTag>,
142}
143
144#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
146#[serde(rename_all = "snake_case")]
147#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
148#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
149pub struct AnnotationLineEndOptions {
150 pub start: AnnotationLineEnd,
152 pub end: AnnotationLineEnd,
154}
155
156#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
158#[serde(rename_all = "snake_case")]
159#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
160#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
161pub struct AnnotationTextOptions {
162 pub x: AnnotationTextAlignmentX,
164 pub y: AnnotationTextAlignmentY,
166 pub text: String,
168 pub point_size: u32,
170}
171
172#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
174#[serde(rename_all = "snake_case")]
175#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
176#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
177pub struct AnnotationMbdControlFrame {
178 pub symbol: MbdSymbol,
180 pub diameter_symbol: Option<MbdSymbol>,
182 pub tolerance: f64,
184 pub modifier: Option<MbdSymbol>,
186 pub primary_datum: Option<char>,
188 pub secondary_datum: Option<char>,
190 pub tertiary_datum: Option<char>,
192}
193
194#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
196#[serde(rename_all = "snake_case")]
197#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
198#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
199pub struct AnnotationMbdBasicDimension {
200 pub symbol: Option<MbdSymbol>,
202 pub dimension: Option<f64>,
204 pub tolerance: f64,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
210#[serde(rename_all = "snake_case")]
211#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
212#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
213pub struct AnnotationBasicDimension {
214 pub from_entity_id: Uuid,
216
217 pub from_entity_pos: Point2d<f64>,
219
220 pub to_entity_id: Uuid,
222
223 pub to_entity_pos: Point2d<f64>,
225
226 pub dimension: AnnotationMbdBasicDimension,
228
229 pub plane_id: Uuid,
231
232 pub offset: Point2d<f64>,
234
235 pub precision: u32,
237
238 pub font_scale: f32,
240
241 pub font_point_size: u32,
243}
244
245#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
247#[serde(rename_all = "snake_case")]
248#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
249#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
250pub struct AnnotationFeatureControl {
251 pub entity_id: Uuid,
253
254 pub entity_pos: Point2d<f64>,
256
257 pub leader_type: AnnotationLineEnd,
259
260 pub dimension: Option<AnnotationMbdBasicDimension>,
262
263 pub control_frame: Option<AnnotationMbdControlFrame>,
265
266 pub defined_datum: Option<char>,
268
269 pub prefix: Option<String>,
271
272 pub suffix: Option<String>,
274
275 pub plane_id: Uuid,
277
278 pub offset: Point2d<f64>,
280
281 pub precision: u32,
283
284 pub font_scale: f32,
286
287 pub font_point_size: u32,
289}
290
291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
293#[serde(rename_all = "snake_case")]
294#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
295#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
296pub struct AnnotationFeatureTag {
297 pub entity_id: Uuid,
299
300 pub entity_pos: Point2d<f64>,
302
303 pub leader_type: AnnotationLineEnd,
305
306 pub key: String,
308
309 pub value: String,
311
312 pub show_key: bool,
314
315 pub plane_id: Uuid,
317
318 pub offset: Point2d<f64>,
320
321 pub font_scale: f32,
323
324 pub font_point_size: u32,
326}
327
328#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
332#[serde(rename_all = "snake_case", tag = "type")]
333#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
334#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
335pub enum DistanceType {
336 Euclidean {},
338 OnAxis {
340 axis: GlobalAxis,
342 },
343}
344
345#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
347#[serde(rename_all = "snake_case", tag = "type")]
348#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
349#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
350pub enum OriginType {
351 #[default]
353 Local,
354 Global,
356 Custom {
358 origin: Point3d<f64>,
360 },
361}
362
363#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
365#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
366#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
367pub struct Color {
368 pub r: f32,
370 pub g: f32,
372 pub b: f32,
374 pub a: f32,
376}
377
378#[allow(missing_docs)]
380#[derive(
381 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
382)]
383#[serde(rename_all = "lowercase")]
384#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
385#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
386pub enum AnnotationTextAlignmentX {
387 Left,
388 Center,
389 Right,
390}
391
392#[allow(missing_docs)]
394#[derive(
395 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
396)]
397#[serde(rename_all = "lowercase")]
398#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
399#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
400pub enum AnnotationTextAlignmentY {
401 Bottom,
402 Center,
403 Top,
404}
405
406#[allow(missing_docs)]
408#[derive(
409 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
410)]
411#[serde(rename_all = "lowercase")]
412#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
413#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
414pub enum AnnotationLineEnd {
415 None,
416 Arrow,
417 Dot,
418}
419
420#[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 AnnotationType {
428 T2D,
430 T3D,
432}
433
434#[derive(
436 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
437)]
438#[serde(rename_all = "lowercase")]
439#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
440#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
441pub enum MbdStandard {
442 AsmeY14_5,
444}
445
446#[allow(missing_docs)]
449#[derive(
450 Default,
451 Display,
452 FromStr,
453 Copy,
454 Eq,
455 PartialEq,
456 Debug,
457 JsonSchema,
458 Deserialize,
459 Serialize,
460 Sequence,
461 Clone,
462 Ord,
463 PartialOrd,
464)]
465#[serde(rename_all = "lowercase")]
466#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
467#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
468#[repr(u16)]
469pub enum MbdSymbol {
470 #[default]
471 None = 0,
472 ArcLength = 174,
473 Between = 175,
474 Degrees = 176,
475 PlusMinus = 177,
476 Angularity = 178,
477 Cylindricity = 179,
478 Roundness = 180,
479 Concentricity = 181,
480 Straightness = 182,
481 Parallelism = 183,
482 Flatness = 184,
483 ProfileOfLine = 185,
484 SurfaceProfile = 186,
485 Symmetry = 187,
486 Perpendicularity = 188,
487 Runout = 189,
488 TotalRunout = 190,
489 Position = 191,
490 CenterLine = 192,
491 PartingLine = 193,
492 IsoEnvelope = 195,
493 IsoEnvelopeNonY145M = 196,
494 FreeState = 197,
495 StatisticalTolerance = 198,
496 ContinuousFeature = 199,
497 Independency = 200,
498 Depth = 201,
499 Start = 202,
500 LeastCondition = 203,
501 MaxCondition = 204,
502 ConicalTaper = 205,
503 Projected = 206,
504 Slope = 207,
505 Micro = 208,
506 TangentPlane = 210,
507 Unilateral = 211,
508 SquareFeature = 212,
509 Countersink = 213,
510 SpotFace = 214,
511 Target = 215,
512 Diameter = 216,
513 Radius = 217,
514 SphericalRadius = 218,
515 SphericalDiameter = 219,
516 ControlledRadius = 220,
517 BoxStart = 123,
518 BoxBar = 162,
519 BoxBarBetween = 124,
520 LetterBackwardUnderline = 95,
521 PunctuationBackwardUnderline = 92,
522 ModifierBackwardUnderline = 126,
523 NumericBackwardUnderline = 96,
524 BoxEnd = 125,
525 DatumUp = 166,
526 DatumLeft = 168,
527 DatumRight = 167,
528 DatumDown = 165,
529 DatumTriangle = 295,
530 HalfSpace = 236,
531 QuarterSpace = 237,
532 EighthSpace = 238,
533 ModifierSpace = 239,
534}
535
536#[derive(
538 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
539)]
540#[serde(rename_all = "lowercase")]
541#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
542#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
543pub enum CameraDragInteractionType {
544 Pan,
546 Rotate,
548 RotateTrackball,
550 Zoom,
552}
553
554#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
557#[serde(rename_all = "snake_case", tag = "type")]
558#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
559#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
560pub enum PathSegment {
561 Line {
564 end: Point3d<LengthUnit>,
566 relative: bool,
568 },
569 Arc {
572 center: Point2d<LengthUnit>,
574 radius: LengthUnit,
576 start: Angle,
578 end: Angle,
580 relative: bool,
582 },
583 Bezier {
587 control1: Point3d<LengthUnit>,
589 control2: Point3d<LengthUnit>,
591 end: Point3d<LengthUnit>,
593 relative: bool,
595 },
596 TangentialArc {
598 radius: LengthUnit,
601 offset: Angle,
603 },
604 TangentialArcTo {
607 to: Point3d<LengthUnit>,
611 angle_snap_increment: Option<Angle>,
613 },
614 ArcTo {
616 interior: Point3d<LengthUnit>,
618 end: Point3d<LengthUnit>,
620 relative: bool,
622 },
623 CircularInvolute {
626 start_radius: LengthUnit,
629 end_radius: LengthUnit,
632 angle: Angle,
635 reverse: bool,
638 },
639 Ellipse {
641 center: Point2d<LengthUnit>,
643 major_axis: Point2d<LengthUnit>,
645 minor_radius: LengthUnit,
647 start_angle: Angle,
649 end_angle: Angle,
651 },
652 ConicTo {
655 interior: Point2d<LengthUnit>,
657 end: Point2d<LengthUnit>,
659 start_tangent: Point2d<LengthUnit>,
661 end_tangent: Point2d<LengthUnit>,
663 relative: bool,
665 },
666}
667
668#[derive(Clone, Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
670#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
671#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
672pub struct Angle {
673 pub unit: UnitAngle,
675 pub value: f64,
677}
678
679impl Angle {
680 pub fn to_degrees(self) -> f64 {
682 match self.unit {
683 UnitAngle::Degrees => self.value,
684 UnitAngle::Radians => self.value.to_degrees(),
685 }
686 }
687 pub fn to_radians(self) -> f64 {
689 match self.unit {
690 UnitAngle::Degrees => self.value.to_radians(),
691 UnitAngle::Radians => self.value,
692 }
693 }
694 pub const fn from_degrees(value: f64) -> Self {
696 Self {
697 unit: UnitAngle::Degrees,
698 value,
699 }
700 }
701 pub const fn from_radians(value: f64) -> Self {
703 Self {
704 unit: UnitAngle::Radians,
705 value,
706 }
707 }
708 pub const fn turn() -> Self {
710 Self::from_degrees(360.0)
711 }
712 pub const fn half_circle() -> Self {
714 Self::from_degrees(180.0)
715 }
716 pub const fn quarter_circle() -> Self {
718 Self::from_degrees(90.0)
719 }
720 pub const fn zero() -> Self {
722 Self::from_degrees(0.0)
723 }
724}
725
726impl Default for Angle {
728 fn default() -> Self {
730 Self::zero()
731 }
732}
733
734impl PartialOrd for Angle {
735 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
736 match (self.unit, other.unit) {
737 (UnitAngle::Degrees, UnitAngle::Degrees) => self.value.partial_cmp(&other.value),
739 (UnitAngle::Radians, UnitAngle::Radians) => self.value.partial_cmp(&other.value),
740 _ => self.to_degrees().partial_cmp(&other.to_degrees()),
741 }
742 }
743}
744
745impl std::ops::Add for Angle {
746 type Output = Self;
747
748 fn add(self, rhs: Self) -> Self::Output {
749 Self {
750 unit: UnitAngle::Degrees,
751 value: self.to_degrees() + rhs.to_degrees(),
752 }
753 }
754}
755
756impl std::ops::AddAssign for Angle {
757 fn add_assign(&mut self, rhs: Self) {
758 match self.unit {
759 UnitAngle::Degrees => {
760 self.value += rhs.to_degrees();
761 }
762 UnitAngle::Radians => {
763 self.value += rhs.to_radians();
764 }
765 }
766 }
767}
768
769#[derive(
771 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
772)]
773#[serde(rename_all = "lowercase")]
774#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
775#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
776pub enum SceneSelectionType {
777 Replace,
779 Add,
781 Remove,
783}
784
785#[allow(missing_docs)]
787#[derive(
788 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
789)]
790#[serde(rename_all = "snake_case")]
791#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
792#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
793pub enum SceneToolType {
794 CameraRevolve,
795 Select,
796 Move,
797 SketchLine,
798 SketchTangentialArc,
799 SketchCurve,
800 SketchCurveMod,
801}
802
803#[allow(missing_docs)]
805#[derive(
806 Display,
807 FromStr,
808 Copy,
809 Eq,
810 PartialEq,
811 Debug,
812 JsonSchema,
813 Deserialize,
814 Serialize,
815 Sequence,
816 Clone,
817 Ord,
818 PartialOrd,
819 Default,
820)]
821#[serde(rename_all = "snake_case")]
822#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
823#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
824pub enum PathComponentConstraintBound {
825 #[default]
826 Unconstrained,
827 PartiallyConstrained,
828 FullyConstrained,
829}
830
831#[allow(missing_docs)]
833#[derive(
834 Display,
835 FromStr,
836 Copy,
837 Eq,
838 PartialEq,
839 Debug,
840 JsonSchema,
841 Deserialize,
842 Serialize,
843 Sequence,
844 Clone,
845 Ord,
846 PartialOrd,
847 Default,
848)]
849#[serde(rename_all = "snake_case")]
850#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
851#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
852pub enum PathComponentConstraintType {
853 #[default]
854 Unconstrained,
855 Vertical,
856 Horizontal,
857 EqualLength,
858 Parallel,
859 AngleBetween,
860}
861
862#[allow(missing_docs)]
864#[derive(
865 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
866)]
867#[serde(rename_all = "snake_case")]
868#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
869#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
870pub enum PathCommand {
871 MoveTo,
872 LineTo,
873 BezCurveTo,
874 NurbsCurveTo,
875 AddArc,
876}
877
878#[allow(missing_docs)]
880#[derive(
881 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
882)]
883#[serde(rename_all = "lowercase")]
884#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
885#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
886#[repr(u8)]
887pub enum EntityType {
888 Entity,
889 Object,
890 Path,
891 Curve,
892 Solid2D,
893 Solid3D,
894 Edge,
895 Face,
896 Plane,
897 Vertex,
898}
899
900#[allow(missing_docs)]
902#[derive(
903 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
904)]
905#[serde(rename_all = "snake_case")]
906#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
907#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
908pub enum CurveType {
909 Line,
910 Arc,
911 Nurbs,
912}
913
914#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
916#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
917pub struct ExportFile {
918 pub name: String,
920 pub contents: crate::base64::Base64Data,
922}
923
924#[cfg(feature = "python")]
925#[pyo3_stub_gen::derive::gen_stub_pymethods]
926#[pyo3::pymethods]
927impl ExportFile {
928 #[getter]
929 fn contents(&self) -> Vec<u8> {
930 self.contents.0.clone()
931 }
932
933 #[getter]
934 fn name(&self) -> String {
935 self.name.clone()
936 }
937}
938
939#[derive(
941 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
942)]
943#[serde(rename_all = "lowercase")]
944#[display(style = "lowercase")]
945#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
946#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
947#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
948pub enum FileExportFormat {
949 Fbx,
951 Glb,
958 Gltf,
969 Obj,
973 Ply,
975 Step,
977 Stl,
979}
980
981#[derive(
983 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
984)]
985#[serde(rename_all = "lowercase")]
986#[display(style = "lowercase")]
987#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
988#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
989pub enum FileExportFormat2d {
990 Dxf,
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 FileImportFormat {
1003 Fbx,
1005 Gltf,
1007 Obj,
1011 Ply,
1013 Sldprt,
1015 Step,
1017 Stl,
1019}
1020
1021#[derive(Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd)]
1023#[serde(rename_all = "snake_case")]
1024#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1025#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1026pub enum EngineErrorCode {
1027 BadRequest = 1,
1031 InternalEngine,
1033}
1034
1035impl From<EngineErrorCode> for http::StatusCode {
1036 fn from(e: EngineErrorCode) -> Self {
1037 match e {
1038 EngineErrorCode::BadRequest => Self::BAD_REQUEST,
1039 EngineErrorCode::InternalEngine => Self::INTERNAL_SERVER_ERROR,
1040 }
1041 }
1042}
1043
1044#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1047#[serde(rename_all = "snake_case")]
1048#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1049#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1050pub enum ExtrudeMethod {
1051 New,
1054 #[default]
1057 Merge,
1058}
1059
1060#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1062#[serde(rename_all = "snake_case")]
1063#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1064#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1065pub enum ExtrudeReference {
1066 EntityReference {
1069 entity_id: Uuid,
1071 },
1072 Axis {
1074 axis: Point3d<f64>,
1076 #[serde(default)]
1079 point: Point3d<LengthUnit>,
1080 },
1081 Point {
1083 point: Point3d<LengthUnit>,
1085 },
1086}
1087
1088#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1090#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1091#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1092pub struct ExtrudedFaceInfo {
1093 pub bottom: Option<Uuid>,
1098 pub top: Uuid,
1100 pub sides: Vec<SideFace>,
1102}
1103
1104#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
1106#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1107#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1108pub struct SideFace {
1109 pub path_id: Uuid,
1111 pub face_id: Uuid,
1113}
1114
1115#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
1117#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1118#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1119pub struct CameraSettings {
1120 pub pos: Point3d,
1122
1123 pub center: Point3d,
1125
1126 pub up: Point3d,
1128
1129 pub orientation: Quaternion,
1131
1132 pub fov_y: Option<f32>,
1134
1135 pub ortho_scale: Option<f32>,
1137
1138 pub ortho: bool,
1140}
1141
1142#[allow(missing_docs)]
1143#[repr(u8)]
1144#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
1145#[serde(rename_all = "snake_case")]
1146#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1147#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1148pub enum WorldCoordinateSystem {
1149 #[default]
1150 RightHandedUpZ,
1151 RightHandedUpY,
1152}
1153
1154#[allow(missing_docs)]
1155#[repr(C)]
1156#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1157#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1158#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1159pub struct CameraViewState {
1160 pub pivot_rotation: Quaternion,
1161 pub pivot_position: Point3d,
1162 pub eye_offset: f32,
1163 pub fov_y: f32,
1164 pub ortho_scale_factor: f32,
1165 pub is_ortho: bool,
1166 pub ortho_scale_enabled: bool,
1167 pub world_coord_system: WorldCoordinateSystem,
1168}
1169
1170impl Default for CameraViewState {
1171 fn default() -> Self {
1172 CameraViewState {
1173 pivot_rotation: Default::default(),
1174 pivot_position: Default::default(),
1175 eye_offset: 10.0,
1176 fov_y: 45.0,
1177 ortho_scale_factor: 1.6,
1178 is_ortho: false,
1179 ortho_scale_enabled: true,
1180 world_coord_system: Default::default(),
1181 }
1182 }
1183}
1184
1185#[cfg(feature = "cxx")]
1186impl_extern_type! {
1187 [Trivial]
1188 CameraViewState = "Endpoints::CameraViewState"
1189}
1190
1191impl From<CameraSettings> for crate::output::DefaultCameraZoom {
1192 fn from(settings: CameraSettings) -> Self {
1193 Self { settings }
1194 }
1195}
1196impl From<CameraSettings> for crate::output::CameraDragMove {
1197 fn from(settings: CameraSettings) -> Self {
1198 Self { settings }
1199 }
1200}
1201impl From<CameraSettings> for crate::output::CameraDragEnd {
1202 fn from(settings: CameraSettings) -> Self {
1203 Self { settings }
1204 }
1205}
1206impl From<CameraSettings> for crate::output::DefaultCameraGetSettings {
1207 fn from(settings: CameraSettings) -> Self {
1208 Self { settings }
1209 }
1210}
1211impl From<CameraSettings> for crate::output::ZoomToFit {
1212 fn from(settings: CameraSettings) -> Self {
1213 Self { settings }
1214 }
1215}
1216impl From<CameraSettings> for crate::output::OrientToFace {
1217 fn from(settings: CameraSettings) -> Self {
1218 Self { settings }
1219 }
1220}
1221impl From<CameraSettings> for crate::output::ViewIsometric {
1222 fn from(settings: CameraSettings) -> Self {
1223 Self { settings }
1224 }
1225}
1226
1227#[derive(Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, PartialOrd, Default)]
1229#[serde(rename_all = "snake_case")]
1230#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1231#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1232pub struct PerspectiveCameraParameters {
1233 pub fov_y: Option<f32>,
1235 pub z_near: Option<f32>,
1237 pub z_far: Option<f32>,
1239}
1240
1241#[derive(
1243 Default,
1244 Display,
1245 FromStr,
1246 Copy,
1247 Eq,
1248 PartialEq,
1249 Debug,
1250 JsonSchema,
1251 Deserialize,
1252 Serialize,
1253 Sequence,
1254 Clone,
1255 Ord,
1256 PartialOrd,
1257)]
1258#[serde(rename_all = "snake_case")]
1259#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1260#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1261pub enum CameraMovement {
1262 #[default]
1264 Vantage,
1265 None,
1267}
1268
1269#[derive(
1271 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1272)]
1273#[serde(rename_all = "lowercase")]
1274#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1275#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1276pub enum GlobalAxis {
1277 X,
1279 Y,
1281 Z,
1283}
1284
1285#[derive(
1287 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
1288)]
1289#[serde(rename_all = "snake_case")]
1290#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1291#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1292#[repr(u8)]
1293pub enum ExtrusionFaceCapType {
1294 None,
1296 Top,
1298 Bottom,
1300 Both,
1302}
1303
1304#[allow(missing_docs)]
1306#[derive(
1307 Display,
1308 FromStr,
1309 Copy,
1310 Eq,
1311 PartialEq,
1312 Debug,
1313 JsonSchema,
1314 Deserialize,
1315 Serialize,
1316 Sequence,
1317 Clone,
1318 Ord,
1319 PartialOrd,
1320 Default,
1321)]
1322#[serde(rename_all = "lowercase")]
1323#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1324#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1325pub enum PostEffectType {
1326 Phosphor,
1327 Ssao,
1328 #[default]
1329 NoEffect,
1330}
1331
1332#[cfg(feature = "cxx")]
1335impl_extern_type! {
1336 [Trivial]
1337 FileImportFormat = "Enums::_FileImportFormat"
1339 FileExportFormat = "Enums::_FileExportFormat"
1340 CameraDragInteractionType = "Enums::_CameraDragInteractionType"
1342 SceneSelectionType = "Enums::_SceneSelectionType"
1344 SceneToolType = "Enums::_SceneToolType"
1345 EntityType = "Enums::_EntityType"
1346 AnnotationType = "Enums::_AnnotationType"
1347 AnnotationTextAlignmentX = "Enums::_AnnotationTextAlignmentX"
1348 AnnotationTextAlignmentY = "Enums::_AnnotationTextAlignmentY"
1349 AnnotationLineEnd = "Enums::_AnnotationLineEnd"
1350 MbdStandard = "Enums::_MBDStandard"
1351 MbdSymbol = "Enums::_MBDSymbol"
1352
1353 CurveType = "Enums::_CurveType"
1354 PathCommand = "Enums::_PathCommand"
1355 PathComponentConstraintBound = "Enums::_PathComponentConstraintBound"
1356 PathComponentConstraintType = "Enums::_PathComponentConstraintType"
1357 ExtrusionFaceCapType = "Enums::_ExtrusionFaceCapType"
1358
1359 EngineErrorCode = "Enums::_ErrorCode"
1361 GlobalAxis = "Enums::_GlobalAxis"
1362 OriginType = "Enums::_OriginType"
1363
1364 PostEffectType = "Enums::_PostEffectType"
1366}
1367
1368fn bool_true() -> bool {
1369 true
1370}
1371fn same_scale() -> Point3d<f64> {
1372 Point3d::uniform(1.0)
1373}
1374
1375fn z_axis() -> Point3d<f64> {
1376 Point3d { x: 0.0, y: 0.0, z: 1.0 }
1377}
1378
1379impl ExtrudedFaceInfo {
1380 pub fn list_faces(self) -> Vec<ExtrusionFaceInfo> {
1383 let mut face_infos: Vec<_> = self
1384 .sides
1385 .into_iter()
1386 .map(|side| ExtrusionFaceInfo {
1387 curve_id: Some(side.path_id),
1388 face_id: Some(side.face_id),
1389 cap: ExtrusionFaceCapType::None,
1390 })
1391 .collect();
1392 face_infos.push(ExtrusionFaceInfo {
1393 curve_id: None,
1394 face_id: Some(self.top),
1395 cap: ExtrusionFaceCapType::Top,
1396 });
1397 if let Some(bottom) = self.bottom {
1398 face_infos.push(ExtrusionFaceInfo {
1399 curve_id: None,
1400 face_id: Some(bottom),
1401 cap: ExtrusionFaceCapType::Bottom,
1402 });
1403 }
1404 face_infos
1405 }
1406}
1407
1408#[cfg(test)]
1409mod tests {
1410 use schemars::schema_for;
1411
1412 use super::*;
1413
1414 #[test]
1415 fn check_transformby_deprecated() {
1416 let s = schema_for!(TransformBy<Point3d>);
1417 let pretty = serde_json::to_string_pretty(&s).unwrap();
1418 println!("{pretty}");
1419 let tests: Vec<(OriginType, TransformBy<Point3d>)> = vec![
1420 (
1422 OriginType::Local,
1423 TransformBy {
1424 property: Point3d::default(),
1425 set: true,
1426 #[allow(deprecated)] is_local: true,
1428 origin: None,
1429 },
1430 ),
1431 (
1434 OriginType::Local,
1435 TransformBy {
1436 property: Point3d::default(),
1437 set: true,
1438 #[allow(deprecated)] is_local: false,
1440 origin: Some(OriginType::Local),
1441 },
1442 ),
1443 (
1446 OriginType::Custom {
1447 origin: Point3d::uniform(2.0),
1448 },
1449 TransformBy {
1450 property: Point3d::default(),
1451 set: true,
1452 #[allow(deprecated)] is_local: false,
1454 origin: Some(OriginType::Custom{origin: Point3d::uniform(2.0)}),
1455 },
1456 ),
1457 ];
1458 for (expected, input) in tests {
1459 let actual = input.get_origin();
1460 assert_eq!(actual, expected);
1461 }
1462 }
1463
1464 #[test]
1465 fn test_angle_comparison() {
1466 let a = Angle::from_degrees(90.0);
1467 assert!(a < Angle::from_degrees(91.0));
1468 assert!(a > Angle::from_degrees(89.0));
1469 assert!(a <= Angle::from_degrees(90.0));
1470 assert!(a >= Angle::from_degrees(90.0));
1471 let b = Angle::from_radians(std::f64::consts::FRAC_PI_4);
1472 assert!(b < Angle::from_radians(std::f64::consts::FRAC_PI_2));
1473 assert!(b > Angle::from_radians(std::f64::consts::FRAC_PI_8));
1474 assert!(b <= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1475 assert!(b >= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1476 assert!(a > b);
1478 assert!(a >= b);
1479 assert!(b < a);
1480 assert!(b <= a);
1481 let c = Angle::from_radians(std::f64::consts::FRAC_PI_2 * 3.0);
1482 assert!(a < c);
1483 assert!(a <= c);
1484 assert!(c > a);
1485 assert!(c >= a);
1486 }
1487}
1488
1489#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
1491#[schemars(rename = "TransformByFor{T}")]
1492#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1493#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1494pub struct TransformBy<T> {
1495 pub property: T,
1497 pub set: bool,
1502 #[deprecated(note = "Use the `origin` field instead.")]
1505 pub is_local: bool,
1506 #[serde(default)]
1510 pub origin: Option<OriginType>,
1511}
1512
1513impl<T> TransformBy<T> {
1514 pub fn get_origin(&self) -> OriginType {
1518 if let Some(origin) = self.origin {
1519 return origin;
1520 }
1521 #[expect(
1522 deprecated,
1523 reason = "Must fall back to the deprecated field if the API client isn't using the new field yet."
1524 )]
1525 if self.is_local {
1526 OriginType::Local
1527 } else {
1528 OriginType::Global
1529 }
1530 }
1531}
1532
1533#[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, Default)]
1536#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1537#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1538pub struct ComponentTransform {
1539 pub translate: Option<TransformBy<Point3d<LengthUnit>>>,
1541 pub rotate_rpy: Option<TransformBy<Point3d<f64>>>,
1544 pub rotate_angle_axis: Option<TransformBy<Point4d<f64>>>,
1548 pub scale: Option<TransformBy<Point3d<f64>>>,
1550}
1551
1552#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
1555#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1556#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1557pub enum Opposite<T> {
1558 #[default]
1560 None,
1561 Symmetric,
1563 Other(T),
1565}
1566
1567impl<T: JsonSchema> JsonSchema for Opposite<T> {
1568 fn schema_name() -> String {
1569 format!("OppositeFor{}", T::schema_name())
1570 }
1571
1572 fn schema_id() -> std::borrow::Cow<'static, str> {
1573 std::borrow::Cow::Owned(format!("{}::Opposite<{}>", module_path!(), T::schema_id()))
1574 }
1575
1576 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1577 SchemaObject {
1578 instance_type: Some(schemars::schema::InstanceType::String.into()),
1579 ..Default::default()
1580 }
1581 .into()
1582 }
1583}
1584
1585#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1588#[serde(rename_all = "snake_case")]
1589#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1590#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1591pub enum CutStrategy {
1592 Basic,
1595 Csg,
1598 #[default]
1600 Automatic,
1601}
1602
1603#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1605#[serde(rename_all = "snake_case")]
1606#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1607#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1608pub enum RelativeTo {
1609 #[default]
1611 SketchPlane,
1612 TrajectoryCurve,
1614}