ifc_material/layer/
set.rs1use ifc_model::EntityId;
4
5use crate::view::{borrowed_entity, optional_text, required_number, required_refs, MaterialView};
6use crate::{MaterialError, MaterialResult};
7
8borrowed_entity!(MaterialLayerSet, "IFCMATERIALLAYERSET");
9
10impl<'m> MaterialLayerSet<'m> {
11 pub fn layer_ids(self) -> MaterialResult<Vec<EntityId>> {
14 required_refs(
15 "IFCMATERIALLAYERSET",
16 self.id(),
17 self.entity(),
18 0,
19 "MaterialLayers",
20 1,
21 )
22 }
23
24 pub fn name(self) -> MaterialResult<Option<&'m str>> {
26 optional_text(
27 "IFCMATERIALLAYERSET",
28 self.id(),
29 self.entity(),
30 1,
31 "LayerSetName",
32 )
33 }
34
35 pub fn description(self) -> MaterialResult<Option<&'m str>> {
37 optional_text(
38 "IFCMATERIALLAYERSET",
39 self.id(),
40 self.entity(),
41 2,
42 "Description",
43 )
44 }
45}
46
47impl<'m> MaterialView<'m> {
48 pub fn layer_sets(self) -> impl Iterator<Item = MaterialLayerSet<'m>> + 'm {
50 self.model()
51 .of_type("IFCMATERIALLAYERSET")
52 .map(|(id, entity)| MaterialLayerSet::from_known(id, entity))
53 }
54
55 pub fn total_thickness(self, set: MaterialLayerSet<'m>) -> MaterialResult<f64> {
57 let mut total = 0.0;
58 for layer_id in set.layer_ids()? {
59 let layer = self.entity(set.id(), layer_id)?;
60 if !layer.is_type("IFCMATERIALLAYER") && !layer.is_type("IFCMATERIALLAYERWITHOFFSETS") {
61 return Err(MaterialError::ReferenceType {
62 source_id: set.id(),
63 target: layer_id,
64 expected: "IFCMATERIALLAYER",
65 actual: layer.type_name.to_string(),
66 });
67 }
68 let thickness =
69 required_number("IFCMATERIALLAYER", layer_id, layer, 1, "LayerThickness")?;
70 if thickness < 0.0 {
71 return Err(MaterialError::InvalidValue {
72 entity: "IFCMATERIALLAYER",
73 id: layer_id,
74 attribute: "LayerThickness",
75 value: "expected a non-negative length".to_owned(),
76 });
77 }
78 total += thickness;
79 if !total.is_finite() {
80 return Err(MaterialError::InvalidValue {
81 entity: "IFCMATERIALLAYERSET",
82 id: set.id(),
83 attribute: "TotalThickness",
84 value: "finite layer thicknesses overflowed the aggregate".to_owned(),
85 });
86 }
87 }
88 Ok(total)
89 }
90}