IFCore Deploy
deploy(prod): 2026-02-21T01:10:43Z
51982d6
"""
Shared IFC utility functions used by team adapters.
"""
import ifcopenshell
import ifcopenshell.util.element
# ── Property extraction ──────────────────────────────────────
def get_pset_value(element, pset_name: str, prop_name: str):
"""Return a property value from a named property set, or None."""
try:
psets = ifcopenshell.util.element.get_psets(element)
if pset_name in psets and prop_name in psets[pset_name]:
v = psets[pset_name][prop_name]
if v is not None and v != "":
return v
except Exception:
pass
return None
def search_psets(element, prop_name: str):
"""Search ALL property sets for a property by name. Returns first numeric match."""
try:
psets = ifcopenshell.util.element.get_psets(element)
for _pset_name, props in psets.items():
if isinstance(props, dict) and prop_name in props:
v = props[prop_name]
if v is not None and v != "" and isinstance(v, (int, float)):
return v
except Exception:
pass
return None
# ── Unit helpers ─────────────────────────────────────────────
def to_mm(value_m):
"""Convert a value (assumed metres) to millimetres.
Heuristic: if value > 100 it's probably already in mm.
"""
if value_m is None:
return None
if value_m > 100:
return round(value_m)
return round(value_m * 1000)
def safe_float(x):
"""Try to convert x to float, return None on failure."""
try:
return float(x) if x is not None else None
except (ValueError, TypeError):
return None
# ── Material helpers ─────────────────────────────────────────
def get_material_total_thickness(element):
"""Sum the thicknesses of all material layers (in model units), or None."""
try:
for rel in getattr(element, "HasAssociations", []):
if rel.is_a("IfcRelAssociatesMaterial"):
mat = rel.RelatingMaterial
layers = None
if mat.is_a("IfcMaterialLayerSetUsage"):
layers = mat.ForLayerSet.MaterialLayers
elif mat.is_a("IfcMaterialLayerSet"):
layers = mat.MaterialLayers
if layers:
total = sum(l.LayerThickness for l in layers)
if total > 0:
return total
except Exception:
pass
return None
# ── Element label ────────────────────────────────────────────
def label(element) -> str:
"""Return a readable label for an IFC element."""
name = element.Name or element.GlobalId
return f"{element.is_a()} '{name}'"