use super::GeometryRouter;
use crate::Mesh;
use ifc_lite_core::{DecodedEntity, EntityDecoder, IfcType};
use std::sync::Arc;
impl GeometryRouter {
pub(super) fn mapped_source_single_item(
&self,
mapped_repr: &DecodedEntity,
decoder: &mut EntityDecoder,
) -> Option<u32> {
let items_attr = mapped_repr.get(3)?;
let items = decoder.resolve_ref_list(items_attr).ok()?;
match items.as_slice() {
[only] if only.ifc_type != IfcType::IfcMappedItem => Some(only.id),
_ => None,
}
}
pub(super) fn ensure_shared_mapped_source(
&self,
mapped_repr: &DecodedEntity,
source_id: u32,
decoder: &mut EntityDecoder,
) {
let Some(shared) = self.shared_mapped_item_cache.as_ref() else {
return;
};
if shared
.lock()
.unwrap_or_else(|e| e.into_inner())
.contains_key(&source_id)
{
return;
}
let mut mesh = Mesh::new();
if let Some(items_attr) = mapped_repr.get(3) {
if let Ok(items) = decoder.resolve_ref_list(items_attr) {
for sub_item in items {
if sub_item.ifc_type == IfcType::IfcMappedItem {
continue;
}
if let Some(processor) = self.processors.get(&sub_item.ifc_type) {
if let Ok(mut sub_mesh) = processor.process(
&sub_item,
decoder,
&self.schema,
self.tessellation_quality,
) {
sub_mesh.validate_indices();
self.scale_mesh(&mut sub_mesh);
mesh.merge(&sub_mesh);
}
}
}
}
}
if !mesh.positions.is_empty() && !crate::kernel::budget::tripped() {
shared
.lock()
.unwrap_or_else(|e| e.into_inner())
.insert(source_id, Arc::new(mesh));
}
}
}