///|
fn manifest_node(
index : ModelIndex,
product : Product,
) -> ManifestNode raise ParseError {
let property_sets = property_sets_for_product(index, product)
let geometries = geometries_for_product(index, product)
let bounds = geometries.fold(init=BoundingBox::empty(), (result, geometry) => {
merge_bounds(result, bounds_of_geometry(geometry))
})
{
product_id: product.id,
ifc_type: product.ifc_type,
name: product.name,
kind: product.kind,
property_names: property_sets.fold(init=Array::new(), (result, property_set) => {
for property in property_set.properties {
result.push(property.name)
}
result
}),
geometry_count: geometries.length(),
bounds,
}
}
///|
pub fn render_manifest(model : Model) -> RenderManifest raise ParseError {
let index = model.index()
let nodes = model
.products()
.fold(init=Array::new(), (result, product) => {
result.push(manifest_node(index, product))
result
})
let bounds = nodes.fold(init=BoundingBox::empty(), (result, node) => {
merge_bounds(result, node.bounds)
})
{ schema: model.schema(), nodes, bounds }
}
///|
pub fn RenderManifest::find(
self : RenderManifest,
product_id : Int,
) -> ManifestNode? {
for node in self.nodes {
if node.product_id == product_id {
return Some(node)
}
}
None
}
///|
pub fn RenderManifest::to_json(self : RenderManifest) -> String {
let nodes = self.nodes.map(node => {
"{\"product_id\":" +
node.product_id.to_string() +
",\"type\":" +
json_string(node.ifc_type) +
",\"name\":" +
optional_string_json(node.name) +
",\"properties\":[" +
node.property_names.map(json_string).join(",") +
"]" +
",\"geometry_count\":" +
node.geometry_count.to_string() +
",\"bounds\":{\"min\":" +
point_json(node.bounds.min) +
",\"max\":" +
point_json(node.bounds.max) +
"}}"
})
"{\"schema\":" +
json_string(self.schema) +
",\"bounds\":{\"min\":" +
point_json(self.bounds.min) +
",\"max\":" +
point_json(self.bounds.max) +
"}" +
",\"nodes\":[" +
join_json(nodes) +
"]}"
}
///|
pub fn manifest_product_names(manifest : RenderManifest) -> Array[String] {
manifest.nodes.fold(init=Array::new(), (result, node) => {
match node.name {
Some(name) => result.push(name)
None => ()
}
result
})
}