Skip to main content

kittycad_modeling_cmds/format/
step.rs

1use bon::Builder;
2use parse_display::{Display, FromStr};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::coord;
7
8/// After importing, how should this model's data be represented?
9#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema)]
10#[serde(rename = "StepImportTargetRepresentation", rename_all = "snake_case")]
11#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
12#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
13#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
14#[cfg_attr(
15    feature = "python",
16    pyo3_stub_gen::derive::gen_stub_pyclass_enum,
17    pyo3::pyclass(name = "StepImportTargetRepresentation", from_py_object)
18)]
19#[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
20pub enum TargetRepresentation {
21    /// Mesh of 2D geometry
22    Mesh,
23    /// Boundary representation
24    Brep,
25}
26
27const DEFAULT_REPR: TargetRepresentation = TargetRepresentation::Brep;
28
29/// Import models in STEP format.
30pub mod import {
31    use super::*;
32
33    /// Options for importing STEP format.
34    #[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Builder)]
35    #[serde(default, rename = "StepImportOptions")]
36    #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
37    #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
38    #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
39    #[cfg_attr(
40        feature = "python",
41        pyo3_stub_gen::derive::gen_stub_pyclass,
42        pyo3::pyclass(name = "StepImportOptions", from_py_object)
43    )]
44    #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
45    pub struct Options {
46        /// Co-ordinate system of input data.
47        ///
48        /// Defaults to the [KittyCAD co-ordinate system].
49        ///
50        /// [KittyCAD co-ordinate system]: ../coord/constant.KITTYCAD.html
51        #[builder(default = *coord::KITTYCAD)]
52        pub coords: coord::System,
53
54        /// Splits all closed faces into two open faces.
55        ///
56        /// Defaults to `false` but is implicitly `true` when importing into the engine.
57        #[builder(default)]
58        pub split_closed_faces: bool,
59
60        /// What representation should be used for this file after it's imported?
61        #[builder(default = DEFAULT_REPR)]
62        pub target_representation: TargetRepresentation,
63    }
64
65    #[cfg(feature = "python")]
66    #[pyo3_stub_gen::derive::gen_stub_pymethods]
67    #[pyo3::pymethods]
68    impl Options {
69        #[new]
70        /// Set the options to their defaults.
71        pub fn new() -> Self {
72            Default::default()
73        }
74    }
75
76    impl Default for Options {
77        fn default() -> Self {
78            Self {
79                target_representation: DEFAULT_REPR,
80                coords: *coord::KITTYCAD,
81                split_closed_faces: false,
82            }
83        }
84    }
85}
86
87/// Export models in STEP format.
88pub mod export {
89    use super::*;
90    use crate::units::UnitLength;
91
92    /// Describes the presentation style of the EXPRESS exchange format.
93    #[derive(
94        Default, Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr,
95    )]
96    #[display(style = "snake_case")]
97    #[serde(rename = "StepPresentation", rename_all = "snake_case")]
98    #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
99    #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
100    #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
101    #[cfg_attr(
102        feature = "python",
103        pyo3_stub_gen::derive::gen_stub_pyclass_enum,
104        pyo3::pyclass(name = "StepPresentation", from_py_object)
105    )]
106    #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
107    pub enum Presentation {
108        /// Condenses the text to reduce the size of the file.
109        Compact,
110
111        /// Add extra spaces to make the text more easily readable.
112        ///
113        /// This is the default setting.
114        #[default]
115        Pretty,
116    }
117
118    /// Options for exporting STEP format.
119    #[derive(Clone, Debug, Deserialize, Eq, Hash, JsonSchema, PartialEq, Serialize, Builder)]
120    #[serde(default, rename = "StepExportOptions")]
121    #[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
122    #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
123    #[cfg_attr(
124        feature = "python",
125        pyo3_stub_gen::derive::gen_stub_pyclass,
126        pyo3::pyclass(name = "StepExportOptions", from_py_object)
127    )]
128    #[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
129    #[cfg_attr(not(feature = "unstable_exhaustive"), non_exhaustive)]
130    pub struct Options {
131        /// Co-ordinate system of output data.
132        ///
133        /// Defaults to the [KittyCAD co-ordinate system].
134        ///
135        /// [KittyCAD co-ordinate system]: ../coord/constant.KITTYCAD.html
136        #[builder(default = default_coords())]
137        pub coords: coord::System,
138
139        /// Timestamp override.
140        pub created: Option<chrono::DateTime<chrono::Utc>>,
141
142        /// Export length unit.
143        ///
144        /// Defaults to meters.
145        #[builder(default = default_units())]
146        pub units: UnitLength,
147
148        /// Presentation style.
149        #[builder(default = default_presentation())]
150        pub presentation: Presentation,
151    }
152
153    #[cfg(feature = "python")]
154    #[pyo3_stub_gen::derive::gen_stub_pymethods]
155    #[pyo3::pymethods]
156    impl Options {
157        #[new]
158        /// Set the options to their defaults.
159        pub fn new() -> Self {
160            Default::default()
161        }
162    }
163
164    impl Default for Options {
165        fn default() -> Self {
166            Self {
167                coords: default_coords(),
168                created: None,
169                units: default_units(),
170                presentation: default_presentation(),
171            }
172        }
173    }
174
175    const fn default_presentation() -> Presentation {
176        Presentation::Pretty
177    }
178
179    const fn default_coords() -> coord::System {
180        *coord::KITTYCAD
181    }
182
183    const fn default_units() -> UnitLength {
184        UnitLength::Meters
185    }
186}