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}
105
106#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
108#[serde(rename_all = "snake_case")]
109#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
110#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
111pub struct AnnotationLineEndOptions {
112 pub start: AnnotationLineEnd,
114 pub end: AnnotationLineEnd,
116}
117
118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
120#[serde(rename_all = "snake_case")]
121#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
122#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
123pub struct AnnotationTextOptions {
124 pub x: AnnotationTextAlignmentX,
126 pub y: AnnotationTextAlignmentY,
128 pub text: String,
130 pub point_size: u32,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
138#[serde(rename_all = "snake_case", tag = "type")]
139#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
140#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
141pub enum DistanceType {
142 Euclidean {},
144 OnAxis {
146 axis: GlobalAxis,
148 },
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
153#[serde(rename_all = "snake_case", tag = "type")]
154#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
155#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
156pub enum OriginType {
157 #[default]
159 Local,
160 Global,
162 Custom {
164 origin: Point3d<f64>,
166 },
167}
168
169#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema)]
171#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
172#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
173pub struct Color {
174 pub r: f32,
176 pub g: f32,
178 pub b: f32,
180 pub a: f32,
182}
183
184#[allow(missing_docs)]
186#[derive(
187 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
188)]
189#[serde(rename_all = "lowercase")]
190#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
191#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
192pub enum AnnotationTextAlignmentX {
193 Left,
194 Center,
195 Right,
196}
197
198#[allow(missing_docs)]
200#[derive(
201 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
202)]
203#[serde(rename_all = "lowercase")]
204#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
205#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
206pub enum AnnotationTextAlignmentY {
207 Bottom,
208 Center,
209 Top,
210}
211
212#[allow(missing_docs)]
214#[derive(
215 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
216)]
217#[serde(rename_all = "lowercase")]
218#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
219#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
220pub enum AnnotationLineEnd {
221 None,
222 Arrow,
223}
224
225#[derive(
227 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
228)]
229#[serde(rename_all = "lowercase")]
230#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
231#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
232pub enum AnnotationType {
233 T2D,
235 T3D,
237}
238
239#[derive(
241 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
242)]
243#[serde(rename_all = "lowercase")]
244#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
245#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
246pub enum CameraDragInteractionType {
247 Pan,
249 Rotate,
251 RotateTrackball,
253 Zoom,
255}
256
257#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, PartialEq)]
260#[serde(rename_all = "snake_case", tag = "type")]
261#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
262#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
263pub enum PathSegment {
264 Line {
267 end: Point3d<LengthUnit>,
269 relative: bool,
271 },
272 Arc {
275 center: Point2d<LengthUnit>,
277 radius: LengthUnit,
279 start: Angle,
281 end: Angle,
283 relative: bool,
285 },
286 Bezier {
290 control1: Point3d<LengthUnit>,
292 control2: Point3d<LengthUnit>,
294 end: Point3d<LengthUnit>,
296 relative: bool,
298 },
299 TangentialArc {
301 radius: LengthUnit,
304 offset: Angle,
306 },
307 TangentialArcTo {
310 to: Point3d<LengthUnit>,
314 angle_snap_increment: Option<Angle>,
316 },
317 ArcTo {
319 interior: Point3d<LengthUnit>,
321 end: Point3d<LengthUnit>,
323 relative: bool,
325 },
326 CircularInvolute {
329 start_radius: LengthUnit,
332 end_radius: LengthUnit,
335 angle: Angle,
338 reverse: bool,
341 },
342 Ellipse {
344 center: Point2d<LengthUnit>,
346 major_axis: Point2d<LengthUnit>,
348 minor_radius: LengthUnit,
350 start_angle: Angle,
352 end_angle: Angle,
354 },
355 ConicTo {
358 interior: Point2d<LengthUnit>,
360 end: Point2d<LengthUnit>,
362 start_tangent: Point2d<LengthUnit>,
364 end_tangent: Point2d<LengthUnit>,
366 relative: bool,
368 },
369}
370
371#[derive(Clone, Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize)]
373#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
374#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
375pub struct Angle {
376 pub unit: UnitAngle,
378 pub value: f64,
380}
381
382impl Angle {
383 pub fn to_degrees(self) -> f64 {
385 match self.unit {
386 UnitAngle::Degrees => self.value,
387 UnitAngle::Radians => self.value.to_degrees(),
388 }
389 }
390 pub fn to_radians(self) -> f64 {
392 match self.unit {
393 UnitAngle::Degrees => self.value.to_radians(),
394 UnitAngle::Radians => self.value,
395 }
396 }
397 pub const fn from_degrees(value: f64) -> Self {
399 Self {
400 unit: UnitAngle::Degrees,
401 value,
402 }
403 }
404 pub const fn from_radians(value: f64) -> Self {
406 Self {
407 unit: UnitAngle::Radians,
408 value,
409 }
410 }
411 pub const fn turn() -> Self {
413 Self::from_degrees(360.0)
414 }
415 pub const fn half_circle() -> Self {
417 Self::from_degrees(180.0)
418 }
419 pub const fn quarter_circle() -> Self {
421 Self::from_degrees(90.0)
422 }
423 pub const fn zero() -> Self {
425 Self::from_degrees(0.0)
426 }
427}
428
429impl Default for Angle {
431 fn default() -> Self {
433 Self::zero()
434 }
435}
436
437impl PartialOrd for Angle {
438 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
439 match (self.unit, other.unit) {
440 (UnitAngle::Degrees, UnitAngle::Degrees) => self.value.partial_cmp(&other.value),
442 (UnitAngle::Radians, UnitAngle::Radians) => self.value.partial_cmp(&other.value),
443 _ => self.to_degrees().partial_cmp(&other.to_degrees()),
444 }
445 }
446}
447
448impl std::ops::Add for Angle {
449 type Output = Self;
450
451 fn add(self, rhs: Self) -> Self::Output {
452 Self {
453 unit: UnitAngle::Degrees,
454 value: self.to_degrees() + rhs.to_degrees(),
455 }
456 }
457}
458
459impl std::ops::AddAssign for Angle {
460 fn add_assign(&mut self, rhs: Self) {
461 match self.unit {
462 UnitAngle::Degrees => {
463 self.value += rhs.to_degrees();
464 }
465 UnitAngle::Radians => {
466 self.value += rhs.to_radians();
467 }
468 }
469 }
470}
471
472#[derive(
474 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
475)]
476#[serde(rename_all = "lowercase")]
477#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
478#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
479pub enum SceneSelectionType {
480 Replace,
482 Add,
484 Remove,
486}
487
488#[allow(missing_docs)]
490#[derive(
491 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
492)]
493#[serde(rename_all = "snake_case")]
494#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
495#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
496pub enum SceneToolType {
497 CameraRevolve,
498 Select,
499 Move,
500 SketchLine,
501 SketchTangentialArc,
502 SketchCurve,
503 SketchCurveMod,
504}
505
506#[allow(missing_docs)]
508#[derive(
509 Display,
510 FromStr,
511 Copy,
512 Eq,
513 PartialEq,
514 Debug,
515 JsonSchema,
516 Deserialize,
517 Serialize,
518 Sequence,
519 Clone,
520 Ord,
521 PartialOrd,
522 Default,
523)]
524#[serde(rename_all = "snake_case")]
525#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
526#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
527pub enum PathComponentConstraintBound {
528 #[default]
529 Unconstrained,
530 PartiallyConstrained,
531 FullyConstrained,
532}
533
534#[allow(missing_docs)]
536#[derive(
537 Display,
538 FromStr,
539 Copy,
540 Eq,
541 PartialEq,
542 Debug,
543 JsonSchema,
544 Deserialize,
545 Serialize,
546 Sequence,
547 Clone,
548 Ord,
549 PartialOrd,
550 Default,
551)]
552#[serde(rename_all = "snake_case")]
553#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
554#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
555pub enum PathComponentConstraintType {
556 #[default]
557 Unconstrained,
558 Vertical,
559 Horizontal,
560 EqualLength,
561 Parallel,
562 AngleBetween,
563}
564
565#[allow(missing_docs)]
567#[derive(
568 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
569)]
570#[serde(rename_all = "snake_case")]
571#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
572#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
573pub enum PathCommand {
574 MoveTo,
575 LineTo,
576 BezCurveTo,
577 NurbsCurveTo,
578 AddArc,
579}
580
581#[allow(missing_docs)]
583#[derive(
584 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
585)]
586#[serde(rename_all = "lowercase")]
587#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
588#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
589#[repr(u8)]
590pub enum EntityType {
591 Entity,
592 Object,
593 Path,
594 Curve,
595 Solid2D,
596 Solid3D,
597 Edge,
598 Face,
599 Plane,
600 Vertex,
601}
602
603#[allow(missing_docs)]
605#[derive(
606 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
607)]
608#[serde(rename_all = "snake_case")]
609#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
610#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
611pub enum CurveType {
612 Line,
613 Arc,
614 Nurbs,
615}
616
617#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
619#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
620pub struct ExportFile {
621 pub name: String,
623 pub contents: crate::base64::Base64Data,
625}
626
627#[cfg(feature = "python")]
628#[pyo3_stub_gen::derive::gen_stub_pymethods]
629#[pyo3::pymethods]
630impl ExportFile {
631 #[getter]
632 fn contents(&self) -> Vec<u8> {
633 self.contents.0.clone()
634 }
635
636 #[getter]
637 fn name(&self) -> String {
638 self.name.clone()
639 }
640}
641
642#[derive(
644 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
645)]
646#[serde(rename_all = "lowercase")]
647#[display(style = "lowercase")]
648#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
649#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
650#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
651pub enum FileExportFormat {
652 Fbx,
654 Glb,
661 Gltf,
672 Obj,
676 Ply,
678 Step,
680 Stl,
682}
683
684#[derive(
686 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
687)]
688#[serde(rename_all = "lowercase")]
689#[display(style = "lowercase")]
690#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
691#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
692pub enum FileExportFormat2d {
693 Dxf,
695}
696
697#[derive(
699 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd, Sequence,
700)]
701#[serde(rename_all = "lowercase")]
702#[display(style = "lowercase")]
703#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
704#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
705pub enum FileImportFormat {
706 Fbx,
708 Gltf,
710 Obj,
714 Ply,
716 Sldprt,
718 Step,
720 Stl,
722}
723
724#[derive(Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, Ord, PartialOrd)]
726#[serde(rename_all = "snake_case")]
727#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
728#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
729pub enum EngineErrorCode {
730 BadRequest = 1,
734 InternalEngine,
736}
737
738impl From<EngineErrorCode> for http::StatusCode {
739 fn from(e: EngineErrorCode) -> Self {
740 match e {
741 EngineErrorCode::BadRequest => Self::BAD_REQUEST,
742 EngineErrorCode::InternalEngine => Self::INTERNAL_SERVER_ERROR,
743 }
744 }
745}
746
747#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
750#[serde(rename_all = "snake_case")]
751#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
752#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
753pub enum ExtrudeMethod {
754 New,
757 #[default]
760 Merge,
761}
762
763#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
765#[serde(rename_all = "snake_case")]
766#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
767#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
768pub enum ExtrudeReference {
769 EntityReference {
772 entity_id: Uuid,
774 },
775 Axis {
777 axis: Point3d<f64>,
779 #[serde(default)]
782 point: Point3d<LengthUnit>,
783 },
784 Point {
786 point: Point3d<LengthUnit>,
788 }
789}
790
791#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
793#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
794#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
795pub struct ExtrudedFaceInfo {
796 pub bottom: Option<Uuid>,
801 pub top: Uuid,
803 pub sides: Vec<SideFace>,
805}
806
807#[derive(Debug, PartialEq, Serialize, Deserialize, JsonSchema, Clone)]
809#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
810#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
811pub struct SideFace {
812 pub path_id: Uuid,
814 pub face_id: Uuid,
816}
817
818#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone)]
820#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
821#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
822pub struct CameraSettings {
823 pub pos: Point3d,
825
826 pub center: Point3d,
828
829 pub up: Point3d,
831
832 pub orientation: Quaternion,
834
835 pub fov_y: Option<f32>,
837
838 pub ortho_scale: Option<f32>,
840
841 pub ortho: bool,
843}
844
845#[allow(missing_docs)]
846#[repr(u8)]
847#[derive(Default, Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]
848#[serde(rename_all = "snake_case")]
849#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
850#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
851pub enum WorldCoordinateSystem {
852 #[default]
853 RightHandedUpZ,
854 RightHandedUpY,
855}
856
857#[allow(missing_docs)]
858#[repr(C)]
859#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
860#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
861#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
862pub struct CameraViewState {
863 pub pivot_rotation: Quaternion,
864 pub pivot_position: Point3d,
865 pub eye_offset: f32,
866 pub fov_y: f32,
867 pub ortho_scale_factor: f32,
868 pub is_ortho: bool,
869 pub ortho_scale_enabled: bool,
870 pub world_coord_system: WorldCoordinateSystem,
871}
872
873impl Default for CameraViewState {
874 fn default() -> Self {
875 CameraViewState {
876 pivot_rotation: Default::default(),
877 pivot_position: Default::default(),
878 eye_offset: 10.0,
879 fov_y: 45.0,
880 ortho_scale_factor: 1.6,
881 is_ortho: false,
882 ortho_scale_enabled: true,
883 world_coord_system: Default::default(),
884 }
885 }
886}
887
888#[cfg(feature = "cxx")]
889impl_extern_type! {
890 [Trivial]
891 CameraViewState = "Endpoints::CameraViewState"
892}
893
894impl From<CameraSettings> for crate::output::DefaultCameraZoom {
895 fn from(settings: CameraSettings) -> Self {
896 Self { settings }
897 }
898}
899impl From<CameraSettings> for crate::output::CameraDragMove {
900 fn from(settings: CameraSettings) -> Self {
901 Self { settings }
902 }
903}
904impl From<CameraSettings> for crate::output::CameraDragEnd {
905 fn from(settings: CameraSettings) -> Self {
906 Self { settings }
907 }
908}
909impl From<CameraSettings> for crate::output::DefaultCameraGetSettings {
910 fn from(settings: CameraSettings) -> Self {
911 Self { settings }
912 }
913}
914impl From<CameraSettings> for crate::output::ZoomToFit {
915 fn from(settings: CameraSettings) -> Self {
916 Self { settings }
917 }
918}
919impl From<CameraSettings> for crate::output::OrientToFace {
920 fn from(settings: CameraSettings) -> Self {
921 Self { settings }
922 }
923}
924impl From<CameraSettings> for crate::output::ViewIsometric {
925 fn from(settings: CameraSettings) -> Self {
926 Self { settings }
927 }
928}
929
930#[derive(Copy, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Clone, PartialOrd, Default)]
932#[serde(rename_all = "snake_case")]
933#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
934#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
935pub struct PerspectiveCameraParameters {
936 pub fov_y: Option<f32>,
938 pub z_near: Option<f32>,
940 pub z_far: Option<f32>,
942}
943
944#[derive(
946 Default,
947 Display,
948 FromStr,
949 Copy,
950 Eq,
951 PartialEq,
952 Debug,
953 JsonSchema,
954 Deserialize,
955 Serialize,
956 Sequence,
957 Clone,
958 Ord,
959 PartialOrd,
960)]
961#[serde(rename_all = "snake_case")]
962#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
963#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
964pub enum CameraMovement {
965 #[default]
967 Vantage,
968 None,
970}
971
972#[derive(
974 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
975)]
976#[serde(rename_all = "lowercase")]
977#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
978#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
979pub enum GlobalAxis {
980 X,
982 Y,
984 Z,
986}
987
988#[derive(
990 Display, FromStr, Copy, Eq, PartialEq, Debug, JsonSchema, Deserialize, Serialize, Sequence, Clone, Ord, PartialOrd,
991)]
992#[serde(rename_all = "snake_case")]
993#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
994#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
995#[repr(u8)]
996pub enum ExtrusionFaceCapType {
997 None,
999 Top,
1001 Bottom,
1003 Both,
1005}
1006
1007#[allow(missing_docs)]
1009#[derive(
1010 Display,
1011 FromStr,
1012 Copy,
1013 Eq,
1014 PartialEq,
1015 Debug,
1016 JsonSchema,
1017 Deserialize,
1018 Serialize,
1019 Sequence,
1020 Clone,
1021 Ord,
1022 PartialOrd,
1023 Default,
1024)]
1025#[serde(rename_all = "lowercase")]
1026#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1027#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1028pub enum PostEffectType {
1029 Phosphor,
1030 Ssao,
1031 #[default]
1032 NoEffect,
1033}
1034
1035#[cfg(feature = "cxx")]
1038impl_extern_type! {
1039 [Trivial]
1040 FileImportFormat = "Enums::_FileImportFormat"
1042 FileExportFormat = "Enums::_FileExportFormat"
1043 CameraDragInteractionType = "Enums::_CameraDragInteractionType"
1045 SceneSelectionType = "Enums::_SceneSelectionType"
1047 SceneToolType = "Enums::_SceneToolType"
1048 EntityType = "Enums::_EntityType"
1049 AnnotationType = "Enums::_AnnotationType"
1050 AnnotationTextAlignmentX = "Enums::_AnnotationTextAlignmentX"
1051 AnnotationTextAlignmentY = "Enums::_AnnotationTextAlignmentY"
1052 AnnotationLineEnd = "Enums::_AnnotationLineEnd"
1053
1054 CurveType = "Enums::_CurveType"
1055 PathCommand = "Enums::_PathCommand"
1056 PathComponentConstraintBound = "Enums::_PathComponentConstraintBound"
1057 PathComponentConstraintType = "Enums::_PathComponentConstraintType"
1058 ExtrusionFaceCapType = "Enums::_ExtrusionFaceCapType"
1059
1060 EngineErrorCode = "Enums::_ErrorCode"
1062 GlobalAxis = "Enums::_GlobalAxis"
1063 OriginType = "Enums::_OriginType"
1064
1065 PostEffectType = "Enums::_PostEffectType"
1067}
1068
1069fn bool_true() -> bool {
1070 true
1071}
1072fn same_scale() -> Point3d<f64> {
1073 Point3d::uniform(1.0)
1074}
1075
1076fn z_axis() -> Point3d<f64> {
1077 Point3d { x: 0.0, y: 0.0, z: 1.0 }
1078}
1079
1080impl ExtrudedFaceInfo {
1081 pub fn list_faces(self) -> Vec<ExtrusionFaceInfo> {
1084 let mut face_infos: Vec<_> = self
1085 .sides
1086 .into_iter()
1087 .map(|side| ExtrusionFaceInfo {
1088 curve_id: Some(side.path_id),
1089 face_id: Some(side.face_id),
1090 cap: ExtrusionFaceCapType::None,
1091 })
1092 .collect();
1093 face_infos.push(ExtrusionFaceInfo {
1094 curve_id: None,
1095 face_id: Some(self.top),
1096 cap: ExtrusionFaceCapType::Top,
1097 });
1098 if let Some(bottom) = self.bottom {
1099 face_infos.push(ExtrusionFaceInfo {
1100 curve_id: None,
1101 face_id: Some(bottom),
1102 cap: ExtrusionFaceCapType::Bottom,
1103 });
1104 }
1105 face_infos
1106 }
1107}
1108
1109#[cfg(test)]
1110mod tests {
1111 use schemars::schema_for;
1112
1113 use super::*;
1114
1115 #[test]
1116 fn check_transformby_deprecated() {
1117 let s = schema_for!(TransformBy<Point3d>);
1118 let pretty = serde_json::to_string_pretty(&s).unwrap();
1119 println!("{pretty}");
1120 let tests: Vec<(OriginType, TransformBy<Point3d>)> = vec![
1121 (
1123 OriginType::Local,
1124 TransformBy {
1125 property: Point3d::default(),
1126 set: true,
1127 #[allow(deprecated)] is_local: true,
1129 origin: None,
1130 },
1131 ),
1132 (
1135 OriginType::Local,
1136 TransformBy {
1137 property: Point3d::default(),
1138 set: true,
1139 #[allow(deprecated)] is_local: false,
1141 origin: Some(OriginType::Local),
1142 },
1143 ),
1144 (
1147 OriginType::Custom {
1148 origin: Point3d::uniform(2.0),
1149 },
1150 TransformBy {
1151 property: Point3d::default(),
1152 set: true,
1153 #[allow(deprecated)] is_local: false,
1155 origin: Some(OriginType::Custom{origin: Point3d::uniform(2.0)}),
1156 },
1157 ),
1158 ];
1159 for (expected, input) in tests {
1160 let actual = input.get_origin();
1161 assert_eq!(actual, expected);
1162 }
1163 }
1164
1165 #[test]
1166 fn test_angle_comparison() {
1167 let a = Angle::from_degrees(90.0);
1168 assert!(a < Angle::from_degrees(91.0));
1169 assert!(a > Angle::from_degrees(89.0));
1170 assert!(a <= Angle::from_degrees(90.0));
1171 assert!(a >= Angle::from_degrees(90.0));
1172 let b = Angle::from_radians(std::f64::consts::FRAC_PI_4);
1173 assert!(b < Angle::from_radians(std::f64::consts::FRAC_PI_2));
1174 assert!(b > Angle::from_radians(std::f64::consts::FRAC_PI_8));
1175 assert!(b <= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1176 assert!(b >= Angle::from_radians(std::f64::consts::FRAC_PI_4));
1177 assert!(a > b);
1179 assert!(a >= b);
1180 assert!(b < a);
1181 assert!(b <= a);
1182 let c = Angle::from_radians(std::f64::consts::FRAC_PI_2 * 3.0);
1183 assert!(a < c);
1184 assert!(a <= c);
1185 assert!(c > a);
1186 assert!(c >= a);
1187 }
1188}
1189
1190#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)]
1192#[schemars(rename = "TransformByFor{T}")]
1193#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1194#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1195pub struct TransformBy<T> {
1196 pub property: T,
1198 pub set: bool,
1203 #[deprecated(note = "Use the `origin` field instead.")]
1206 pub is_local: bool,
1207 #[serde(default)]
1211 pub origin: Option<OriginType>,
1212}
1213
1214impl<T> TransformBy<T> {
1215 pub fn get_origin(&self) -> OriginType {
1219 if let Some(origin) = self.origin {
1220 return origin;
1221 }
1222 #[expect(
1223 deprecated,
1224 reason = "Must fall back to the deprecated field if the API client isn't using the new field yet."
1225 )]
1226 if self.is_local {
1227 OriginType::Local
1228 } else {
1229 OriginType::Global
1230 }
1231 }
1232}
1233
1234#[derive(Clone, Debug, PartialEq, Deserialize, JsonSchema, Serialize, Default)]
1237#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1238#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1239pub struct ComponentTransform {
1240 pub translate: Option<TransformBy<Point3d<LengthUnit>>>,
1242 pub rotate_rpy: Option<TransformBy<Point3d<f64>>>,
1245 pub rotate_angle_axis: Option<TransformBy<Point4d<f64>>>,
1249 pub scale: Option<TransformBy<Point3d<f64>>>,
1251}
1252
1253#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
1256#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1257#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1258pub enum Opposite<T> {
1259 #[default]
1261 None,
1262 Symmetric,
1264 Other(T),
1266}
1267
1268impl<T: JsonSchema> JsonSchema for Opposite<T> {
1269 fn schema_name() -> String {
1270 format!("OppositeFor{}", T::schema_name())
1271 }
1272
1273 fn schema_id() -> std::borrow::Cow<'static, str> {
1274 std::borrow::Cow::Owned(format!("{}::Opposite<{}>", module_path!(), T::schema_id()))
1275 }
1276
1277 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
1278 SchemaObject {
1279 instance_type: Some(schemars::schema::InstanceType::String.into()),
1280 ..Default::default()
1281 }
1282 .into()
1283 }
1284}
1285
1286#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
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"))]
1292pub enum CutStrategy {
1293 Basic,
1296 Csg,
1299 #[default]
1301 Automatic,
1302}
1303
1304#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, JsonSchema, Default)]
1306#[serde(rename_all = "snake_case")]
1307#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
1308#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
1309pub enum RelativeTo {
1310 #[default]
1312 SketchPlane,
1313 TrajectoryCurve,
1315}