///|
fn product_kind_name(kind : ProductKind) -> String {
match kind {
Project => "Project"
Site => "Site"
Building => "Building"
Storey => "Storey"
Space => "Space"
Wall => "Wall"
Door => "Door"
Window => "Window"
Beam => "Beam"
Column => "Column"
Slab => "Slab"
Roof => "Roof"
Stair => "Stair"
Ramp => "Ramp"
Opening => "Opening"
Generic => "Generic"
}
}
///|
/// Count products by their normalized IFC family name.
pub fn product_kind_counts(products : Array[Product]) -> Map[String, Int] {
let result : Map[String, Int] = Map([])
for product in products {
result.update_or_default(product_kind_name(product.kind), 1, count => {
count + 1
})
}
result
}
///|
pub fn property_name_counts(
property_sets : Array[PropertySet],
) -> Map[String, Int] {
let result : Map[String, Int] = Map([])
for property_set in property_sets {
for property in property_set.properties {
result.update_or_default(property.name, 1, count => count + 1)
}
}
result
}
///|
pub fn total_estimated_volume(
index : ModelIndex,
products : Array[Product],
) -> Double {
products.fold(init=0.0, (total, product) => {
geometries_for_product(index, product).fold(init=total, (
geometry_total,
geometry,
) => {
match estimated_volume(geometry) {
Some(volume) => geometry_total + volume
None => geometry_total
}
})
})
}
///|
fn geometry_kind_name(kind : GeometryKind) -> String {
match kind {
Extrusion => "Extrusion"
FacetedBrep => "FacetedBrep"
TriangulatedMesh => "TriangulatedMesh"
CsgSolid => "CsgSolid"
Profile => "Profile"
Polyline => "Polyline"
PointCloud => "PointCloud"
Unknown => "Unknown"
}
}
///|
/// Count geometry adapters by their stable output kind name.
pub fn geometry_kind_counts(index : ModelIndex) -> Map[String, Int] {
let result : Map[String, Int] = Map([])
for entity in geometry_entities(index) {
let kind = geometry_for_entity(index, entity).kind
result.update_or_default(geometry_kind_name(kind), 1, count => count + 1)
}
result
}