mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Fix bug where migrating length units didn't change properties. Unit utility for checking attribute types now considers select types too
Changing properties is very critical for IFC2X3 georeferencing which is stored in a pset.
This commit is contained in:
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user