diff --git a/src/ifcopenshell-python/ifcopenshell/util/unit.py b/src/ifcopenshell-python/ifcopenshell/util/unit.py index 475aca0f71..45905ca595 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/unit.py +++ b/src/ifcopenshell-python/ifcopenshell/util/unit.py @@ -749,10 +749,23 @@ def format_length( def is_attr_type( content_type: ifcopenshell_wrapper.parameter_type, ifc_unit_type_name: str, + include_select_types: bool = True ) -> Union[ifcopenshell_wrapper.type_declaration, None]: cur_decl = content_type + + if include_select_types: + if hasattr(cur_decl, "select_list"): + for select_item in cur_decl.select_list(): + if is_attr_type(select_item, ifc_unit_type_name): + return select_item + while hasattr(cur_decl, "declared_type") is True: cur_decl = cur_decl.declared_type() + if include_select_types: + if hasattr(cur_decl, "select_list"): + for select_item in cur_decl.select_list(): + if is_attr_type(select_item, ifc_unit_type_name): + return select_item if hasattr(cur_decl, "name") is False: continue if cur_decl.name() == ifc_unit_type_name: @@ -800,6 +813,9 @@ def iter_element_and_attributes_per_type( if val is None: continue + if isinstance(val, ifcopenshell.entity_instance) and not val.is_a(attr_type_name): + continue + yield element, attr, val @@ -833,8 +849,12 @@ def convert_file_length_units(ifc_file: ifcopenshell.file, target_units: str = " # Traverse all elements and their nested attributes in the file and convert them for element, attr, val in iter_element_and_attributes_per_type(file_patched, "IfcLengthMeasure"): - new_value = convert_value(val) - setattr(element, attr.name(), new_value) + if isinstance(val, ifcopenshell.entity_instance): + new_value = convert_value(val.wrappedValue) + getattr(element, attr.name()).wrappedValue = new_value + else: + new_value = convert_value(val) + setattr(element, attr.name(), new_value) file_patched.remove(old_length) unit_assignment.Units = tuple([new_length, *unit_assignment.Units]) diff --git a/src/ifcopenshell-python/test/util/test_unit.py b/src/ifcopenshell-python/test/util/test_unit.py index 59b3c3371b..29a09fea5c 100644 --- a/src/ifcopenshell-python/test/util/test_unit.py +++ b/src/ifcopenshell-python/test/util/test_unit.py @@ -82,3 +82,13 @@ class TestFormatLength(test.bootstrap.IFC4): assert ( subject.format_length(25.23, 4, unit_system="imperial", input_unit="inch", output_unit="inch") == '25 1/4"' ) + + +class TestIsAttrType(test.bootstrap.IFC4): + def test_run(self): + schema = ifcopenshell.schema_by_name("IFC4") + declaration = schema.declaration_by_name("IfcPropertySingleValue") + nominal_value = declaration.attribute_by_index(2).type_of_attribute() + assert subject.is_attr_type(nominal_value, "IfcValue") + assert subject.is_attr_type(nominal_value, "IfcLengthMeasure") + assert not subject.is_attr_type(nominal_value, "IfcLengthMeasure", include_select_types=False)