use std::io::Cursor;
use cadmpeg_ir::codec::{Codec, DecodeOptions};
use cadmpeg_ir::products::ProductDefinition;
use crate::StepCodec;
const TRANSFORM: &str = "#29=CARTESIAN_POINT('',(0.,0.,0.));\n#30=DIRECTION('',(0.,0.,1.));\n#31=DIRECTION('',(1.,0.,0.));\n#32=AXIS2_PLACEMENT_3D('',#29,#30,#31);\n#33=ITEM_DEFINED_TRANSFORMATION('','',#32,#32);\n";
fn decode_with(entities: &str) -> Vec<ProductDefinition> {
let source = String::from_utf8(
include_bytes!("../../../../tests/fixtures/ap242_geometric_set.p21").to_vec(),
)
.expect("fixture is UTF-8")
.replace(
"ENDSEC;\nEND-ISO-10303-21;",
&format!("{entities}ENDSEC;\nEND-ISO-10303-21;"),
);
StepCodec::default()
.decode(&mut Cursor::new(source), &DecodeOptions::default())
.expect("decode")
.ir()
.model
.product_definitions
.clone()
}
#[test]
fn an_assembly_component_does_not_absorb_the_assemblys_bodies() {
let definitions = decode_with(&format!(
"#14=PRODUCT('ROOT','assembly root that owns the body','',());\n\
#15=PRODUCT_DEFINITION_FORMATION('','',#14);\n\
#16=APPLICATION_CONTEXT('mechanical design');\n\
#17=PRODUCT_DEFINITION_CONTEXT('part definition',#16,'design');\n\
#18=PRODUCT_DEFINITION('root','',#15,#17);\n\
#19=PRODUCT_DEFINITION_SHAPE('','',#18);\n\
#20=SHAPE_DEFINITION_REPRESENTATION(#19,#40);\n\
#40=SHAPE_REPRESENTATION('',(),#2);\n\
#41=SHAPE_REPRESENTATION_RELATIONSHIP('','',#40,#13);\n\
#21=PRODUCT('CHILD','component with no geometry of its own','',());\n\
#22=PRODUCT_DEFINITION_FORMATION('','',#21);\n\
#23=PRODUCT_DEFINITION('child','',#22,#17);\n\
#24=PRODUCT_DEFINITION_SHAPE('','',#23);\n\
#25=SHAPE_REPRESENTATION('',(),#2);\n\
#26=SHAPE_DEFINITION_REPRESENTATION(#24,#25);\n\
#50=SHAPE_REPRESENTATION('',(),#2);\n\
#51=SHAPE_REPRESENTATION_RELATIONSHIP('','',#25,#50);\n\
#27=NEXT_ASSEMBLY_USAGE_OCCURRENCE('u1','','',#18,#23,$);\n\
#28=PRODUCT_DEFINITION_SHAPE('','',#27);\n\
{TRANSFORM}\
#34=(REPRESENTATION_RELATIONSHIP('','',#13,#50) REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#33) SHAPE_REPRESENTATION_RELATIONSHIP());\n\
#35=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#34,#28);\n"
));
assert_eq!(definitions.len(), 2, "{definitions:#?}");
let root = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("ROOT"))
.expect("root definition");
let child = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("CHILD"))
.expect("child definition");
assert!(
child.bodies.is_empty(),
"the component absorbed {} body(ies) from the assembly that places it: {:?}",
child.bodies.len(),
child.bodies
);
assert_eq!(
root.bodies.len(),
1,
"the assembly lost its own body: {:?}",
root.bodies
);
}
#[test]
fn a_transformed_relationship_inside_one_part_keeps_the_parts_body() {
let definitions = decode_with(&format!(
"#14=PRODUCT('PART','part placed into its own geometry','',());\n\
#15=PRODUCT_DEFINITION_FORMATION('','',#14);\n\
#16=APPLICATION_CONTEXT('mechanical design');\n\
#17=PRODUCT_DEFINITION_CONTEXT('part definition',#16,'design');\n\
#18=PRODUCT_DEFINITION('part','',#15,#17);\n\
#19=PRODUCT_DEFINITION_SHAPE('','',#18);\n\
#20=SHAPE_DEFINITION_REPRESENTATION(#19,#40);\n\
#40=SHAPE_REPRESENTATION('',(),#2);\n\
{TRANSFORM}\
#41=(REPRESENTATION_RELATIONSHIP('','',#40,#13) REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#33) SHAPE_REPRESENTATION_RELATIONSHIP());\n"
));
assert_eq!(definitions.len(), 1, "{definitions:#?}");
assert_eq!(
definitions[0].bodies.len(),
1,
"the part lost the body its own relationship reaches: {:?}",
definitions[0].bodies
);
}
#[test]
fn an_assembly_does_not_list_its_components_body_as_its_own() {
let definitions = decode_with(&format!(
"#14=PRODUCT('ROOT','assembly with no geometry of its own','',());\n\
#15=PRODUCT_DEFINITION_FORMATION('','',#14);\n\
#16=APPLICATION_CONTEXT('mechanical design');\n\
#17=PRODUCT_DEFINITION_CONTEXT('part definition',#16,'design');\n\
#18=PRODUCT_DEFINITION('root','',#15,#17);\n\
#19=PRODUCT_DEFINITION_SHAPE('','',#18);\n\
#20=SHAPE_DEFINITION_REPRESENTATION(#19,#40);\n\
#40=SHAPE_REPRESENTATION('',(),#2);\n\
#21=PRODUCT('CHILD','component that owns the body','',());\n\
#22=PRODUCT_DEFINITION_FORMATION('','',#21);\n\
#23=PRODUCT_DEFINITION('child','',#22,#17);\n\
#24=PRODUCT_DEFINITION_SHAPE('','',#23);\n\
#25=SHAPE_REPRESENTATION('',(),#2);\n\
#26=SHAPE_DEFINITION_REPRESENTATION(#24,#25);\n\
#51=SHAPE_REPRESENTATION_RELATIONSHIP('','',#25,#13);\n\
#27=NEXT_ASSEMBLY_USAGE_OCCURRENCE('u1','','',#18,#23,$);\n\
#28=PRODUCT_DEFINITION_SHAPE('','',#27);\n\
{TRANSFORM}\
#34=(REPRESENTATION_RELATIONSHIP('','',#40,#13) REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#33) SHAPE_REPRESENTATION_RELATIONSHIP());\n\
#35=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#34,#28);\n"
));
assert_eq!(definitions.len(), 2, "{definitions:#?}");
let root = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("ROOT"))
.expect("root definition");
let child = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("CHILD"))
.expect("child definition");
assert!(
root.bodies.is_empty(),
"the assembly listed its component's body as its own: {:?}",
root.bodies
);
assert_eq!(
child.bodies.len(),
1,
"the component lost its body: {:?}",
child.bodies
);
}
#[test]
fn an_unresolved_assembly_placement_is_not_followed() {
let definitions = decode_with(&format!(
"#14=PRODUCT('ROOT','assembly root that owns the body','',());\n\
#15=PRODUCT_DEFINITION_FORMATION('','',#14);\n\
#16=APPLICATION_CONTEXT('mechanical design');\n\
#17=PRODUCT_DEFINITION_CONTEXT('part definition',#16,'design');\n\
#18=PRODUCT_DEFINITION('root','',#15,#17);\n\
#19=PRODUCT_DEFINITION_SHAPE('','',#18);\n\
#20=SHAPE_DEFINITION_REPRESENTATION(#19,#40);\n\
#40=SHAPE_REPRESENTATION('',(),#2);\n\
#41=SHAPE_REPRESENTATION_RELATIONSHIP('','',#40,#13);\n\
#21=PRODUCT('CHILD','component with no geometry of its own','',());\n\
#22=PRODUCT_DEFINITION_FORMATION('','',#21);\n\
#23=PRODUCT_DEFINITION('child','',#22,#17);\n\
#24=PRODUCT_DEFINITION_SHAPE('','',#23);\n\
#25=SHAPE_REPRESENTATION('',(),#2);\n\
#26=SHAPE_DEFINITION_REPRESENTATION(#24,#25);\n\
#50=SHAPE_REPRESENTATION('',(),#2);\n\
#51=SHAPE_REPRESENTATION_RELATIONSHIP('','',#25,#50);\n\
#27=NEXT_ASSEMBLY_USAGE_OCCURRENCE('u1','','',#18,#23,$);\n\
{TRANSFORM}\
#34=(REPRESENTATION_RELATIONSHIP('','',#13,#50) REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#33) SHAPE_REPRESENTATION_RELATIONSHIP());\n\
#35=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#34,#24);\n"
));
assert_eq!(definitions.len(), 2, "{definitions:#?}");
let root = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("ROOT"))
.expect("root definition");
let child = definitions
.iter()
.find(|d| d.part_number.as_deref() == Some("CHILD"))
.expect("child definition");
assert!(
child.bodies.is_empty(),
"an unresolved placement gave the component the assembly's body: {:?}",
child.bodies
);
assert_eq!(
root.bodies.len(),
1,
"the assembly lost its own body: {:?}",
root.bodies
);
}