From f3fc55f2463f40ea0daa1bb6424378bc156e5b1a Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 24 Jan 2025 16:12:38 +0500 Subject: [PATCH] Change primitive data type from bool to enum As it also has a third value "UNKNOWN" which has it's own meanig in IFC and therefore IfcLogical cannot be represented by simple booleans. Example in Bonsai - https://i.imgur.com/xuPMcwA.png --- src/bonsai/bonsai/bim/helper.py | 22 ++++++++++++++----- src/bonsai/bonsai/bim/prop.py | 8 +++++-- .../ifcopenshell/util/attribute.py | 4 ++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/bonsai/bonsai/bim/helper.py b/src/bonsai/bonsai/bim/helper.py index 1ecef5a489..da51bbe587 100644 --- a/src/bonsai/bonsai/bim/helper.py +++ b/src/bonsai/bonsai/bim/helper.py @@ -185,11 +185,23 @@ def import_attribute( new.special_type = "FORCE" new.float_value = 0.0 if new.is_null else float(data[attribute.name()]) elif data_type == "enum": - enum_items = ifcopenshell.util.attribute.get_enum_items(attribute) - new.enum_items = json.dumps(enum_items) - add_attribute_enum_items_descriptions(new, enum_items) - if data[new.name]: - new.enum_value = data[new.name] + attribute_type = attribute.type_of_attribute() + is_logical = str(attribute_type) == ">" + enum_value = data[new.name] + if is_logical: + new.special_type = "LOGICAL" + enum_items = ("TRUE", "FALSE", "UNKNOWN") + new.enum_items = json.dumps(enum_items) + if enum_value is not None and enum_value != "UNKNOWN": + # IfcOpenShell returns bool if IfcLogical is True/False. + enum_value = "TRUE" if enum_value else "FALSE" + else: + enum_items = ifcopenshell.util.attribute.get_enum_items(attribute) + new.enum_items = json.dumps(enum_items) + add_attribute_enum_items_descriptions(new, enum_items) + + if enum_value is not None: + new.enum_value = enum_value add_attribute_description(new, data) add_attribute_min_max(attribute, new) diff --git a/src/bonsai/bonsai/bim/prop.py b/src/bonsai/bonsai/bim/prop.py index 0d83a26bdd..eeadea7fcd 100644 --- a/src/bonsai/bonsai/bim/prop.py +++ b/src/bonsai/bonsai/bim/prop.py @@ -275,7 +275,7 @@ def get_display_name(self: "Attribute") -> str: AttributeDataType = Literal["string", "integer", "float", "boolean", "enum", "file"] -AttributeSpecialType = Literal["", "DATE", "DATETIME", "LENGTH", "AREA", "VOLUME", "FORCE"] +AttributeSpecialType = Literal["", "DATE", "DATETIME", "LENGTH", "AREA", "VOLUME", "FORCE", "LOGICAL"] class Attribute(PropertyGroup): @@ -337,7 +337,11 @@ class Attribute(PropertyGroup): return self.string_value.replace("\\n", "\n") if self.data_type == "file": return [f.name for f in self.filepath_value.file_list] - return getattr(self, str(self.get_value_name()), None) + value = getattr(self, str(self.get_value_name()), None) + if self.special_type == "LOGICAL" and value != "UNKNOWN": + # IfcOpenShell expects bool if IfcLogical is True/False. + value = value == "TRUE" + return value def get_value_default(self) -> Union[str, float, int, bool]: data_type = self.data_type diff --git a/src/ifcopenshell-python/ifcopenshell/util/attribute.py b/src/ifcopenshell-python/ifcopenshell/util/attribute.py index b7a241c5f6..f29f60ed8b 100644 --- a/src/ifcopenshell-python/ifcopenshell/util/attribute.py +++ b/src/ifcopenshell-python/ifcopenshell/util/attribute.py @@ -47,9 +47,9 @@ def get_primitive_type( return "float" elif "" in data_type or "" in data_type: return "integer" - elif "" in data_type or "" in data_type: + elif "" in data_type: return "boolean" - elif "" in data_type or "