ifc_rs/objects/wall/
mod.rs1mod deserialize;
2mod serialize;
3
4use std::ops::{Deref, DerefMut};
5
6use ifc_rs_verify_derive::IfcVerify;
7
8use crate::{
9 id::{IdOr, TypedId},
10 ifc_type::{IfcType, IfcVerify},
11 parser::{label::Label, optional::OptionalParameter},
12 prelude::*,
13 relations::rel_associates_material::MaterialRelatable,
14};
15
16use super::StructureType;
17
18#[derive(IfcVerify)]
25pub struct Wall {
26 #[inherited]
27 element: Element,
28
29 pub predefined_type: OptionalParameter<IdOr<WallType>>,
33}
34
35impl Wall {
36 pub fn new(name: impl Into<Label>) -> Self {
37 Self {
38 element: Element::new(Product::new(Object::new(Root::new(name.into())))),
39 predefined_type: OptionalParameter::omitted(),
40 }
41 }
42
43 pub fn predefined_type(
44 mut self,
45 predefined_type: impl Into<IdOr<WallType>>,
46 ifc: &mut IFC,
47 ) -> Self {
48 let id_or: IdOr<_> = predefined_type.into();
49 let id_or: IdOr<_> = id_or.or_insert(ifc).into();
50 self.predefined_type = id_or.into();
51 self
52 }
53}
54
55impl RootBuilder for Wall {
56 fn root_mut(&mut self) -> &mut Root {
57 &mut self.element
58 }
59}
60
61impl ObjectBuilder for Wall {
62 fn object_mut(&mut self) -> &mut Object {
63 &mut self.element
64 }
65}
66
67impl ProductBuilder for Wall {
68 fn product_mut(&mut self) -> &mut Product {
69 &mut self.element
70 }
71}
72
73impl ElementBuilder for Wall {
74 fn element_mut(&mut self) -> &mut Element {
75 &mut self.element
76 }
77}
78
79impl Deref for Wall {
80 type Target = Element;
81
82 fn deref(&self) -> &Self::Target {
83 &self.element
84 }
85}
86
87impl DerefMut for Wall {
88 fn deref_mut(&mut self) -> &mut Self::Target {
89 &mut self.element
90 }
91}
92
93impl IfcType for Wall {
94 fn to_structure(&self) -> Option<&dyn Structure> {
95 Some(self)
96 }
97}
98impl Structure for Wall {
99 fn structure_type(&self) -> Option<StructureType<'_>> {
100 Some(StructureType::Wall(self))
101 }
102}
103impl MaterialRelatable for Wall {}
104
105impl TransformableType for Wall {
106 fn shape(&self) -> Option<TypedId<ProductDefinitionShape>> {
107 self.representation.custom().cloned()
108 }
109}
110
111#[cfg(test)]
112pub mod test {
113 use glam::DVec3;
114 use winnow::Parser;
115
116 use crate::geometry::axis::Axis3D;
117 use crate::geometry::local_placement::LocalPlacement;
118 use crate::geometry::point::Point3D;
119 use crate::geometry::product_definition_shape::test::new_product_definition_shape;
120 use crate::geometry::product_definition_shape::ProductDefinitionShape;
121 use crate::geometry::representation_context::GeometricRepresentationContext;
122 use crate::geometry::representation_subcontext::GeometricRepresentationSubContext;
123 use crate::geometry::shape_representation::ShapeRepresentation;
124 use crate::id::IdOr;
125 use crate::objects::application::Application;
126 use crate::objects::change_action::ChangeAction;
127 use crate::objects::organization::Organization;
128 use crate::objects::owner_history::OwnerHistory;
129 use crate::objects::person::Person;
130 use crate::objects::person_and_org::PersonAndOrganization;
131 use crate::objects::shared::{product::ProductBuilder, root::RootBuilder};
132 use crate::objects::wall::Wall;
133 use crate::parser::timestamp::IfcTimestamp;
134 use crate::parser::IFCParse;
135 use crate::IFC;
136
137 #[test]
138 fn wall_round_trip() {
139 let example = "IFCWALL('0DWgwt6o1FOx7466fPk$jl',#2,$,$,$,#33,#25,$,$);";
140
141 let wall: Wall = Wall::parse().parse(example).unwrap();
142 let str_wall = wall.to_string();
143
144 assert_eq!(example, str_wall);
145 }
146
147 pub fn print_wall_hierarchy(ifc: &IFC) {
148 use crate::objects::wall::Wall;
149
150 for (_, wall) in ifc.data.find_all_of_type::<Wall>() {
151 println!("wall: {wall}");
152
153 if let Some(owner_history) = wall
154 .owner_history
155 .custom()
156 .map(|&id| ifc.data.get_untyped(id))
157 {
158 println!("\towner_history: {owner_history}");
159 }
160
161 if let Some(id) = wall.object_placement.custom() {
162 println!("\tpoint3d: {}", ifc.data.get_untyped(*id));
163 }
164
165 if let Some(representation) = wall
166 .representation
167 .custom()
168 .map(|&id| ifc.data.get_untyped(id))
169 {
170 println!("\trepresentation: {representation}");
171
172 for repr in representation
173 .downcast_ref::<ProductDefinitionShape>()
174 .unwrap()
175 .representations
176 .iter()
177 {
178 let shape = ifc.data.get::<ShapeRepresentation>(*repr);
179 println!("\t\tshape_representation: {shape}");
180
181 let sub_context = ifc
182 .data
183 .get::<GeometricRepresentationSubContext>(shape.context_of_items);
184
185 println!("\t\t\tsub context: {sub_context}");
186
187 let parent_context = ifc
188 .data
189 .get::<GeometricRepresentationContext>(sub_context.parent_context);
190
191 println!("\t\t\t\tcontext: {parent_context}");
192 println!(
193 "\t\t\t\t\tcoord_dims: {}",
194 parent_context.coord_space_dimension
195 );
196
197 let world_coord_system = ifc
198 .data
199 .get::<Axis3D>(parent_context.world_coord_system.into());
200
201 println!("\t\t\t\t\tworld_coord_system: {world_coord_system}");
202 println!(
203 "\t\t\t\t\t\tcoord_system_point: {}",
204 ifc.data.get_untyped(world_coord_system.location)
205 );
206
207 for (index, item) in shape.items(ifc).enumerate() {
208 println!("\t\t\titem {index}: {item}");
209 }
210 }
211 }
212
213 if let Some(id_or) = wall.predefined_type.custom() {
214 match id_or {
215 IdOr::Id(id) => println!("\twall_type: {}", ifc.data.get_untyped(*id)),
216 IdOr::Custom(wall_type) => println!("\twall_type: {}", wall_type),
217 }
218 }
219 }
220 }
221
222 #[test]
223 fn create_wall() {
224 let mut ifc = IFC::default();
225
226 let person_id = ifc.data.insert_new(Person::empty());
227 let application =
228 Application::new(person_id, "0.0.1", "create_wall_test", "IFC4", &mut ifc);
229 let application_id = ifc.data.insert_new(application);
230
231 let person_and_org = PersonAndOrganization::new(
232 person_id,
233 Organization::new(None, "organization_name", None),
234 &mut ifc,
235 );
236
237 let owner_history = OwnerHistory::new(ChangeAction::Added, IfcTimestamp::now())
238 .owning_user(person_and_org, &mut ifc)
239 .owning_application(application_id, &mut ifc);
240
241 let axis = Axis3D::new(Point3D::from(DVec3::new(0.0, 0.0, 0.0)), &mut ifc);
242 let axis_id = ifc.data.insert_new(axis);
243 let local_placement = LocalPlacement::new(axis_id, &mut ifc);
244
245 let representation = new_product_definition_shape(&mut ifc, axis_id.into());
246
247 let wall = Wall::new("global_id_example")
248 .owner_history(owner_history, &mut ifc)
249 .object_placement(local_placement, &mut ifc)
250 .representation(representation, &mut ifc);
251
252 ifc.data.insert_new(wall);
253
254 println!("{}", ifc.data);
255 println!();
256 print_wall_hierarchy(&ifc);
257 }
258}