diff --git a/src/bonsai/bonsai/tool/pset.py b/src/bonsai/bonsai/tool/pset.py index caca6b1039..1a0177e825 100644 --- a/src/bonsai/bonsai/tool/pset.py +++ b/src/bonsai/bonsai/tool/pset.py @@ -252,19 +252,38 @@ class Pset(bonsai.core.tool.Pset): props: bpy.types.PropertyGroup, ) -> None: if pset: - data = ifcopenshell.util.element.get_property_definition(pset) + data = ifcopenshell.util.element.get_property_definition(pset, verbose=True) del data["id"] else: data = {} + simplified_data = {prop_name: prop_data["value"] for prop_name, prop_data in data.items()} + + # For every prop we first ensure that existing prop value type matches the template value type + # to prevent data loss and error casting data. + # Property will be added later by import_pset_from_existing. for prop_template in sorted(pset_template.HasPropertyTemplates, key=lambda p: p.Name): if not prop_template.is_a("IfcSimplePropertyTemplate"): continue # Other types not yet supported + prop_data = data.get(prop_template.Name) if prop_template.TemplateType == "P_SINGLEVALUE": - cls.import_single_value_from_template(pset_template, prop_template, data, props) + if prop_data: + if prop_data["class"] != "IfcPropertySingleValue": + continue + template_data_type = cls.get_prop_template_primitive_type(prop_template) + existing_data_type = prop_data.get("value_type", None) + if existing_data_type and template_data_type != existing_data_type: + continue + continue + cls.import_single_value_from_template(pset_template, prop_template, simplified_data, props) + elif prop_template.TemplateType.startswith("Q_"): - cls.import_single_value_from_template(pset_template, prop_template, data, props) + cls.import_single_value_from_template(pset_template, prop_template, simplified_data, props) + elif prop_template.TemplateType == "P_ENUMERATEDVALUE": - cls.import_enumerated_value_from_template(prop_template, data, props) + if prop_data and prop_data["class"] != "IfcPropertyEnumeratedValue": + continue + cls.import_enumerated_value_from_template(prop_template, simplified_data, props) + else: # NOTE: currently unsupported types: # - P_BOUNDEDVALUE diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py index 6de7ca5f44..eddc927d1a 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py +++ b/src/ifcopenshell-python/ifcopenshell/api/pset/edit_pset.py @@ -411,14 +411,14 @@ class Usecase: raise TypeError(f"'{self.settings['pset']}' is not a valid pset") def get_primary_measure_type(self, name, old_value=None, new_value=None): + if old_value: + return old_value.is_a() if self.pset_template: for prop_template in self.pset_template.HasPropertyTemplates: if prop_template.Name != name: continue return prop_template.PrimaryMeasureType or "IfcLabel" - if old_value: - return old_value.is_a() - elif new_value and hasattr(new_value, "is_a"): + if new_value and hasattr(new_value, "is_a"): return new_value.is_a() elif new_value is not None: if isinstance(new_value, str): diff --git a/src/ifcopenshell-python/ifcopenshell/util/element.py b/src/ifcopenshell-python/ifcopenshell/util/element.py index f36ce8456c..1ff7402051 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/element.py +++ b/src/ifcopenshell-python/ifcopenshell/util/element.py @@ -394,6 +394,7 @@ def get_properties( "id": prop.id(), "class": prop.is_a(), "value": results[prop_name], + "value_type": v.is_a() if v else None, } elif ifc_class == "IfcPropertyEnumeratedValue": # 2 IfcPropertyEnumeratedValue.EnumerationValues