2021-01-07 19:09:55 +11:00
|
|
|
import ifcopenshell
|
2021-03-24 16:09:29 +11:00
|
|
|
import ifcopenshell.util.attribute
|
2021-04-29 19:35:21 +10:00
|
|
|
import ifcopenshell.util.pset
|
2021-01-07 19:09:55 +11:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class Data:
|
|
|
|
|
products = {}
|
|
|
|
|
psets = {}
|
2021-01-13 21:26:10 +11:00
|
|
|
qtos = {}
|
2021-05-13 11:55:25 +10:00
|
|
|
properties = {}
|
2021-01-07 19:09:55 +11:00
|
|
|
|
2021-02-03 17:30:19 +11:00
|
|
|
@classmethod
|
|
|
|
|
def purge(cls):
|
|
|
|
|
cls.products = {}
|
|
|
|
|
cls.psets = {}
|
|
|
|
|
cls.qtos = {}
|
2021-05-13 11:55:25 +10:00
|
|
|
cls.properties = {}
|
2021-02-03 17:30:19 +11:00
|
|
|
|
2021-01-07 19:09:55 +11:00
|
|
|
@classmethod
|
2021-03-25 10:48:31 +11:00
|
|
|
def load(cls, file, product_id):
|
2021-01-07 19:09:55 +11:00
|
|
|
if not file:
|
|
|
|
|
return
|
|
|
|
|
product = file.by_id(product_id)
|
2021-01-13 21:26:10 +11:00
|
|
|
cls.products[product_id] = {"psets": set(), "qtos": set()}
|
2021-01-07 19:09:55 +11:00
|
|
|
if product.is_a("IfcElementType"):
|
|
|
|
|
cls.add_type_product_psets(product, product_id)
|
2021-01-17 21:53:31 +11:00
|
|
|
elif product.is_a("IfcMaterialDefinition"):
|
|
|
|
|
cls.add_material_psets(product, product_id)
|
2021-01-07 19:09:55 +11:00
|
|
|
else:
|
|
|
|
|
cls.add_product_psets(product, product_id)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def add_type_product_psets(cls, product, product_id):
|
|
|
|
|
if not hasattr(product, "HasPropertySets") or not product.HasPropertySets:
|
2021-03-24 16:09:29 +11:00
|
|
|
return # TODO
|
2021-01-07 19:09:55 +11:00
|
|
|
for definition in product.HasPropertySets:
|
|
|
|
|
if definition.is_a("IfcPropertySet"):
|
|
|
|
|
cls.add_pset(definition, product_id)
|
|
|
|
|
|
2021-01-17 21:53:31 +11:00
|
|
|
@classmethod
|
|
|
|
|
def add_material_psets(cls, product, product_id):
|
|
|
|
|
if not product.HasProperties:
|
|
|
|
|
return
|
|
|
|
|
for pset in product.HasProperties:
|
|
|
|
|
cls.add_pset(pset, product_id)
|
|
|
|
|
|
2021-01-07 19:09:55 +11:00
|
|
|
@classmethod
|
|
|
|
|
def add_product_psets(cls, product, product_id):
|
|
|
|
|
if not hasattr(product, "IsDefinedBy") or not product.IsDefinedBy:
|
|
|
|
|
return
|
|
|
|
|
for definition in product.IsDefinedBy:
|
|
|
|
|
if not definition.is_a("IfcRelDefinesByProperties"):
|
|
|
|
|
continue
|
|
|
|
|
if definition.RelatingPropertyDefinition.is_a("IfcPropertySet"):
|
|
|
|
|
cls.add_pset(definition.RelatingPropertyDefinition, product_id)
|
2021-01-13 21:26:10 +11:00
|
|
|
elif definition.RelatingPropertyDefinition.is_a("IfcElementQuantity"):
|
|
|
|
|
cls.add_qto(definition.RelatingPropertyDefinition, product_id)
|
2021-01-07 19:09:55 +11:00
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def add_pset(cls, pset, product_id):
|
2021-05-13 11:55:25 +10:00
|
|
|
data = pset.get_info()
|
2021-05-30 13:32:59 +02:00
|
|
|
if not pset.is_a("IfcMaterialProperties"):
|
|
|
|
|
del data["OwnerHistory"]
|
|
|
|
|
del data["HasProperties"]
|
2021-05-13 11:55:25 +10:00
|
|
|
if hasattr(pset, "HasProperties"):
|
|
|
|
|
props = pset.HasProperties or []
|
|
|
|
|
elif hasattr(pset, "Properties"):
|
|
|
|
|
props = pset.Properties or []
|
|
|
|
|
# TODO: support more than single values
|
|
|
|
|
data["Properties"] = [p.id() for p in props if p.is_a("IfcPropertySingleValue")]
|
|
|
|
|
cls.psets[pset.id()] = data
|
|
|
|
|
cls.products[product_id]["psets"].add(pset.id())
|
2021-01-07 19:09:55 +11:00
|
|
|
for prop in props:
|
2021-05-13 11:55:25 +10:00
|
|
|
# TODO: support more than single values
|
|
|
|
|
if prop.is_a("IfcPropertySingleValue"):
|
|
|
|
|
cls.load_prop(prop)
|
2021-01-13 21:26:10 +11:00
|
|
|
|
|
|
|
|
@classmethod
|
2021-05-13 11:55:25 +10:00
|
|
|
def load_prop(cls, prop):
|
|
|
|
|
data = prop.get_info()
|
|
|
|
|
if prop.is_a("IfcProperty"):
|
|
|
|
|
# TODO: support units
|
|
|
|
|
del data["Unit"]
|
|
|
|
|
if prop.NominalValue is not None:
|
|
|
|
|
data["NominalValue"] = prop.NominalValue.wrappedValue
|
|
|
|
|
elif prop.is_a("IfcPhysicalQuantity"):
|
|
|
|
|
# TODO: support units
|
|
|
|
|
del data["Unit"]
|
|
|
|
|
# For convenience, which trumps correctness in this case
|
|
|
|
|
data["NominalValue"] = prop[3]
|
|
|
|
|
cls.properties[prop.id()] = data
|
2021-01-13 21:26:10 +11:00
|
|
|
|
|
|
|
|
@classmethod
|
2021-05-13 11:55:25 +10:00
|
|
|
def add_qto(cls, qto, product_id):
|
|
|
|
|
data = qto.get_info()
|
|
|
|
|
del data["OwnerHistory"]
|
|
|
|
|
del data["Quantities"]
|
|
|
|
|
# TODO: support more than just simple quantities
|
|
|
|
|
# We call it properties for convenience, not for correctness
|
|
|
|
|
data["Properties"] = [q.id() for q in qto.Quantities or [] if q.is_a("IfcPhysicalSimpleQuantity")]
|
|
|
|
|
cls.qtos[qto.id()] = data
|
|
|
|
|
cls.products[product_id]["qtos"].add(qto.id())
|
|
|
|
|
for quantity in qto.Quantities or []:
|
|
|
|
|
if quantity.is_a("IfcPhysicalSimpleQuantity"):
|
|
|
|
|
cls.load_prop(quantity)
|