#[derive(Debug, Clone)]
pub struct StepWriteOptions {
pub schema: StepSchema,
pub unsupported: StepUnsupportedPolicy,
pub product_name: String,
pub author: String,
pub organization: String,
pub timestamp: String,
pub originating_system: String,
}
impl Default for StepWriteOptions {
fn default() -> Self {
StepWriteOptions {
schema: StepSchema::Ap214,
unsupported: StepUnsupportedPolicy::Report,
product_name: "cadmpeg_model".to_string(),
author: String::new(),
organization: String::new(),
timestamp: String::new(),
originating_system: "cadmpeg".to_string(),
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum StepUnsupportedPolicy {
#[default]
Report,
Reject,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum StepSchema {
Ap203Edition1,
Ap203Edition2,
#[default]
Ap214,
Ap242Edition1,
Ap242Edition2,
Ap242Edition3,
}
impl StepSchema {
pub const fn file_schema(self) -> &'static str {
match self {
Self::Ap203Edition1 => "CONFIG_CONTROL_DESIGN",
Self::Ap203Edition2 => "AP203_CONFIGURATION_CONTROLLED_3D_DESIGN_OF_MECHANICAL_PARTS_AND_ASSEMBLIES_MIM_LF { 1 0 10303 403 2 1 2 }",
Self::Ap214 => "AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }",
Self::Ap242Edition1 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 1 1 4 }",
Self::Ap242Edition2 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 3 1 4 }",
Self::Ap242Edition3 => "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF { 1 0 10303 442 4 1 4 }",
}
}
pub(crate) fn ap242_edition(identifier: &str) -> Option<&'static str> {
const NAME: &str = "AP242_MANAGED_MODEL_BASED_3D_ENGINEERING_MIM_LF";
let (name, oid) = split_schema_identifier(identifier)?;
if !name.eq_ignore_ascii_case(NAME) {
return None;
}
match oid.as_deref() {
Some([1, 0, 10303, 442, 1, 1, 4]) => Some("edition 1"),
Some([1, 0, 10303, 442, 3, 1, 4]) => Some("edition 2"),
Some([1, 0, 10303, 442, 4, 1, 4]) => Some("edition 3"),
_ => None,
}
}
pub(crate) const fn supports_tessellation(self) -> bool {
matches!(
self,
Self::Ap242Edition1 | Self::Ap242Edition2 | Self::Ap242Edition3
)
}
pub(crate) const fn supports_semantic_pmi(self) -> bool {
self.supports_tessellation()
}
pub(crate) const fn supports_visibility(self) -> bool {
!matches!(self, Self::Ap203Edition1)
}
pub(crate) const fn application_protocol(self) -> (&'static str, &'static str, i32) {
match self {
Self::Ap203Edition1 => (
"configuration controlled 3d designs of mechanical parts and assemblies",
"config_control_design",
1994,
),
Self::Ap203Edition2 => (
"configuration controlled 3d designs of mechanical parts and assemblies",
"ap203_configuration_controlled_3d_design_of_mechanical_parts_and_assemblies",
2011,
),
Self::Ap214 => ("automotive design", "automotive_design", 2000),
Self::Ap242Edition1 => (
"managed model based 3d engineering",
"ap242_managed_model_based_3d_engineering",
2014,
),
Self::Ap242Edition2 => (
"managed model based 3d engineering",
"ap242_managed_model_based_3d_engineering",
2020,
),
Self::Ap242Edition3 => (
"managed model based 3d engineering",
"ap242_managed_model_based_3d_engineering",
2022,
),
}
}
}
fn split_schema_identifier(identifier: &str) -> Option<(&str, Option<Vec<i64>>)> {
let identifier = identifier.trim();
let Some(open) = identifier.rfind('{') else {
return Some((identifier, None));
};
if !identifier.ends_with('}') || identifier[..open].trim().is_empty() {
return None;
}
let oid = identifier[open + 1..identifier.len() - 1]
.split_whitespace()
.map(str::parse::<i64>)
.collect::<Result<Vec<i64>, _>>()
.ok()?;
(!oid.is_empty()).then(|| (identifier[..open].trim_end(), Some(oid)))
}