use ifc_model::{Entity, EntityId, Model};
use crate::slots::Slots;
pub mod slot {
#[cfg_attr(not(feature = "lowering"), allow(dead_code))]
pub const OBJECT_PLACEMENT: usize = 5;
pub const REPRESENTATION: usize = 6;
}
#[derive(Debug, Clone, Copy)]
pub struct Product<'m> {
slots: Slots<'m>,
}
impl<'m> Product<'m> {
pub fn new(id: EntityId, entity: &'m Entity) -> Self {
Self {
slots: Slots::new(id, entity),
}
}
#[cfg_attr(not(feature = "lowering"), allow(dead_code))]
pub fn object_placement(&self) -> Option<EntityId> {
self.slots.opt_ref(slot::OBJECT_PLACEMENT)
}
pub fn representation(&self) -> Option<EntityId> {
self.slots.opt_ref(slot::REPRESENTATION)
}
}
pub fn geometric_products(model: &Model) -> Vec<EntityId> {
let mut found: Vec<EntityId> = model
.iter()
.filter(|(id, entity)| {
let product = Product::new(*id, entity);
product.representation().is_some_and(|shape| {
model.get(shape).is_some_and(|e| {
e.type_name.contains("PRODUCTREPRESENTATION")
|| e.type_name.contains("PRODUCTDEFINITIONSHAPE")
})
})
})
.map(|(id, _)| id)
.collect();
found.sort();
found
}