1#[derive(Debug, Clone)]
11pub struct StepWriteOptions {
12 pub schema: StepSchema,
14 pub unsupported: StepUnsupportedPolicy,
16 pub product_name: String,
21 pub author: String,
23 pub organization: String,
25 pub timestamp: String,
30 pub originating_system: String,
32}
33
34impl Default for StepWriteOptions {
35 fn default() -> Self {
36 StepWriteOptions {
37 schema: StepSchema::Ap214,
38 unsupported: StepUnsupportedPolicy::Report,
39 product_name: "cadmpeg_model".to_string(),
40 author: String::new(),
41 organization: String::new(),
42 timestamp: String::new(),
43 originating_system: "cadmpeg".to_string(),
44 }
45 }
46}
47
48#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
50pub enum StepUnsupportedPolicy {
51 #[default]
53 Report,
54 Reject,
56}
57
58#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
63pub enum StepSchema {
64 Ap203Edition1,
66 Ap203Edition2,
68 #[default]
70 Ap214,
71 Ap242Edition1,
73 Ap242Edition2,
75 Ap242Edition3,
77}
78
79impl StepSchema {
80 pub const fn file_schema(self) -> &'static str {
82 match self {
83 Self::Ap203Edition1 => "CONFIG_CONTROL_DESIGN",
84 Self::Ap203Edition2 => "AP203_CONFIGURATION_CONTROLLED_3D_DESIGN_OF_MECHANICAL_PARTS_AND_ASSEMBLIES_MIM_LF { 1 0 10303 403 2 1 2 }",
85 Self::Ap214 => "AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }",
86 Self::Ap242Edition1 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 1 1 4 }",
87 Self::Ap242Edition2 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 3 1 4 }",
88 Self::Ap242Edition3 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 4 1 4 }",
89 }
90 }
91
92 pub(crate) fn ap242_edition(identifier: &str) -> Option<&'static str> {
93 const NAME: &str = "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF";
94 let (name, oid) = schema_identifier_arcs(identifier)?;
95 if !name.eq_ignore_ascii_case(NAME) {
96 return None;
97 }
98 match oid.as_deref() {
99 Some([1, 0, 10303, 442, 1, 1, 4]) => Some("edition 1"),
100 Some([1, 0, 10303, 442, 3, 1, 4]) => Some("edition 2"),
101 Some([1, 0, 10303, 442, 4, 1, 4]) => Some("edition 3"),
102 _ => None,
103 }
104 }
105
106 pub(crate) const fn supports_tessellation(self) -> bool {
107 matches!(
108 self,
109 Self::Ap242Edition1 | Self::Ap242Edition2 | Self::Ap242Edition3
110 )
111 }
112
113 pub(crate) const fn supports_semantic_pmi(self) -> bool {
114 self.supports_tessellation()
115 }
116
117 pub(crate) const fn supports_visibility(self) -> bool {
118 !matches!(self, Self::Ap203Edition1)
119 }
120
121 pub(crate) const fn application_protocol(self) -> (&'static str, &'static str, i32) {
122 match self {
123 Self::Ap203Edition1 => (
124 "configuration controlled 3d designs of mechanical parts and assemblies",
125 "config_control_design",
126 1994,
127 ),
128 Self::Ap203Edition2 => (
129 "configuration controlled 3d designs of mechanical parts and assemblies",
130 "ap203_configuration_controlled_3d_design_of_mechanical_parts_and_assemblies",
131 2011,
132 ),
133 Self::Ap214 => ("automotive design", "automotive_design", 2000),
134 Self::Ap242Edition1 => (
135 "managed model based 3d engineering",
136 "ap242_managed_model_based_3d_engineering",
137 2014,
138 ),
139 Self::Ap242Edition2 => (
140 "managed model based 3d engineering",
141 "ap242_managed_model_based_3d_engineering",
142 2020,
143 ),
144 Self::Ap242Edition3 => (
145 "managed model based 3d engineering",
146 "ap242_managed_model_based_3d_engineering",
147 2022,
148 ),
149 }
150 }
151}
152
153fn schema_identifier_arcs(identifier: &str) -> Option<(&str, Option<Vec<u64>>)> {
160 let (name, object_identifier) =
161 crate::parse::schema_identifier::split_schema_identifier(identifier)?;
162 let Some(object_identifier) = object_identifier else {
163 return Some((name, None));
164 };
165 if name.is_empty() {
166 return None;
167 }
168 let arcs = object_identifier
169 .split_whitespace()
170 .map(str::parse::<u64>)
171 .collect::<Result<Vec<u64>, _>>()
172 .ok()?;
173 (arcs.len() >= 2).then_some((name, Some(arcs)))
174}