use axiolid_model::NodeId;
use ifc_model::EntityId;
use crate::error::{GeometryError, GeometryResult};
use crate::input::context::product_representation_frame;
pub use crate::input::product::geometric_products;
use crate::input::representation::{
select_product_representation, Representation, RepresentationPurpose,
};
use crate::lower::dispatch::lower_representation_item;
use crate::lower::session::LoweringSession;
pub use crate::constraint::product_world_transform;
pub use crate::input::representation::select_shape_representation;
pub fn lower_product_items(
session: &mut LoweringSession<'_>,
product: EntityId,
) -> GeometryResult<Option<NodeId>> {
lower_product_representation(session, product, RepresentationPurpose::Body)
}
pub fn lower_product_representation(
session: &mut LoweringSession<'_>,
product: EntityId,
purpose: RepresentationPurpose,
) -> GeometryResult<Option<NodeId>> {
let Some(world) =
product_representation_frame(session.model(), session.units(), product, purpose)?
else {
return Ok(None);
};
let Some(representation) = select_product_representation(session.model(), product, purpose)?
else {
return Ok(None);
};
let entity = session
.model()
.get(representation)
.ok_or(GeometryError::MissingEntity {
referrer: product,
missing: representation,
})?;
let items = Representation::new(representation, entity).items()?;
let mut roots = Vec::with_capacity(items.len());
for item in items {
roots.push(lower_representation_item(session, item, world)?);
}
match roots.len() {
0 => Ok(None),
1 => Ok(Some(roots[0])),
_ => Ok(Some(session.node_for(
product,
axiolid_model::GeometryNode::Collection(roots),
)?)),
}
}