use crate::{Error, Mesh, Result};
use ifc_lite_core::{DecodedEntity, EntityDecoder, IfcSchema, IfcType};
use crate::router::GeometryProcessor;
use super::extrusion::ExtrudedAreaSolidProcessor;
use super::tessellated::TriangulatedFaceSetProcessor;
use super::brep::FacetedBrepProcessor;
use super::boolean::BooleanClippingProcessor;
use super::swept::{SweptDiskSolidProcessor, RevolvedAreaSolidProcessor};
pub struct MappedItemProcessor;
impl MappedItemProcessor {
pub fn new() -> Self {
Self
}
}
impl GeometryProcessor for MappedItemProcessor {
fn process(
&self,
entity: &DecodedEntity,
decoder: &mut EntityDecoder,
schema: &IfcSchema,
) -> Result<Mesh> {
let source_attr = entity
.get(0)
.ok_or_else(|| Error::geometry("MappedItem missing MappingSource".to_string()))?;
let source_entity = decoder
.resolve_ref(source_attr)?
.ok_or_else(|| Error::geometry("Failed to resolve MappingSource".to_string()))?;
let mapped_rep_attr = source_entity.get(1).ok_or_else(|| {
Error::geometry("RepresentationMap missing MappedRepresentation".to_string())
})?;
let mapped_rep = decoder
.resolve_ref(mapped_rep_attr)?
.ok_or_else(|| Error::geometry("Failed to resolve MappedRepresentation".to_string()))?;
let items_attr = mapped_rep
.get(3)
.ok_or_else(|| Error::geometry("Representation missing Items".to_string()))?;
let items = decoder.resolve_ref_list(items_attr)?;
let mut mesh = Mesh::new();
for item in items {
let item_mesh = match item.ifc_type {
IfcType::IfcExtrudedAreaSolid => {
let processor = ExtrudedAreaSolidProcessor::new(schema.clone());
processor.process(&item, decoder, schema)?
}
IfcType::IfcTriangulatedFaceSet => {
let processor = TriangulatedFaceSetProcessor::new();
processor.process(&item, decoder, schema)?
}
IfcType::IfcFacetedBrep => {
let processor = FacetedBrepProcessor::new();
processor.process(&item, decoder, schema)?
}
IfcType::IfcSweptDiskSolid => {
let processor = SweptDiskSolidProcessor::new(schema.clone());
processor.process(&item, decoder, schema)?
}
IfcType::IfcBooleanClippingResult | IfcType::IfcBooleanResult => {
let processor = BooleanClippingProcessor::new();
processor.process(&item, decoder, schema)?
}
IfcType::IfcRevolvedAreaSolid => {
let processor = RevolvedAreaSolidProcessor::new(schema.clone());
processor.process(&item, decoder, schema)?
}
_ => continue, };
mesh.merge(&item_mesh);
}
Ok(mesh)
}
fn supported_types(&self) -> Vec<IfcType> {
vec![IfcType::IfcMappedItem]
}
}
impl Default for MappedItemProcessor {
fn default() -> Self {
Self::new()
}
}