diff --git a/src/speckleifc/converter/data_object_converter.py b/src/speckleifc/converter/data_object_converter.py index 79a0b27..13d922d 100644 --- a/src/speckleifc/converter/data_object_converter.py +++ b/src/speckleifc/converter/data_object_converter.py @@ -4,6 +4,8 @@ from ifcopenshell.entity_instance import entity_instance from specklepy.objects.base import Base from specklepy.objects.data_objects import DataObject +from speckleifc.property_extraction import extract_properties + def data_object_to_speckle( display_value: list[Base], @@ -15,7 +17,7 @@ def data_object_to_speckle( data_object = DataObject( applicationId=guid, - properties={}, + properties=extract_properties(step_element), name=name or guid, displayValue=display_value, ) diff --git a/src/speckleifc/converter/spatial_element_converter.py b/src/speckleifc/converter/spatial_element_converter.py index d4aebe8..036278a 100644 --- a/src/speckleifc/converter/spatial_element_converter.py +++ b/src/speckleifc/converter/spatial_element_converter.py @@ -5,6 +5,8 @@ from specklepy.objects.base import Base from specklepy.objects.data_objects import DataObject from specklepy.objects.models.collections.collection import Collection +from speckleifc.property_extraction import extract_properties + def spatial_element_to_speckle( display_value: list[Base], @@ -31,7 +33,7 @@ def _convert_as_data_object( name = cast(str, step_element.Name or step_element.LongName or guid) data_object = DataObject( applicationId=guid, - properties={}, + properties=extract_properties(step_element), name=name, displayValue=display_value, ) diff --git a/src/speckleifc/property_extraction.py b/src/speckleifc/property_extraction.py new file mode 100644 index 0000000..b13e5cb --- /dev/null +++ b/src/speckleifc/property_extraction.py @@ -0,0 +1,50 @@ +from typing import Any + +from ifcopenshell.entity_instance import entity_instance + + +def extract_properties(element: entity_instance) -> dict[str, object]: + result: dict[str, object] = {} + + for rel in getattr(element, "IsDefinedBy", []): + if not rel.is_a("IfcRelDefinesByProperties"): + continue + + prop_set = rel.RelatingPropertyDefinition + if not prop_set.is_a("IfcPropertySet"): + continue + + set_name = prop_set.Name + properties: dict[str, Any] = {} + + for prop in prop_set.HasProperties: + name = prop.Name + + if prop.is_a("IfcPropertySingleValue"): + val = prop.NominalValue + if val is not None: + properties[name] = ( + val.wrappedValue if hasattr(val, "wrappedValue") else val + ) + elif prop.is_a("IfcPropertyListValue"): + values = getattr(prop, "ListValues", None) + if values: + properties[name] = [ + v.wrappedValue if hasattr(v, "wrappedValue") else v + for v in values + ] + elif prop.is_a("IfcPropertyEnumeratedValue"): + values = getattr(prop, "EnumerationValues", None) + if values: + properties[name] = [ + v.wrappedValue if hasattr(v, "wrappedValue") else v + for v in values + ] + + # elif prop.is_a("IfcPropertyTableValue"): + # properties[name] = #not sure if we want to support these... + + if properties: + result[set_name] = properties + + return result