From 1cdd44996b9e3d00e120efedd84e7f8af805773e Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Mon, 1 Sep 2025 09:47:41 +0200 Subject: [PATCH 1/5] Add classification system to the Object Information, Clasifiction References Subpanel --- .../bonsai/bim/module/classification/data.py | 11 ++++++++ .../bonsai/bim/module/classification/ui.py | 26 +++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/classification/data.py b/src/bonsai/bonsai/bim/module/classification/data.py index acc88af10a..c3a54aa372 100644 --- a/src/bonsai/bonsai/bim/module/classification/data.py +++ b/src/bonsai/bonsai/bim/module/classification/data.py @@ -104,6 +104,17 @@ class ReferencesData: if element: for reference in ifcopenshell.util.classification.get_references(element): data = reference.get_info() + + if reference.ReferencedSource: + if reference.ReferencedSource.is_a("IfcClassification"): + data["ClassificationSystemName"] = reference.ReferencedSource.Name + elif reference.ReferencedSource.is_a("IfcClassificationReference"): + current = reference.ReferencedSource + while current.ReferencedSource and current.ReferencedSource.is_a("IfcClassificationReference"): + current = current.ReferencedSource + if current.ReferencedSource and current.ReferencedSource.is_a("IfcClassification"): + data["ClassificationSystemName"] = current.ReferencedSource.Name + del data["ReferencedSource"] results.append(data) return results diff --git a/src/bonsai/bonsai/bim/module/classification/ui.py b/src/bonsai/bonsai/bim/module/classification/ui.py index 344c247af2..acd27803b2 100644 --- a/src/bonsai/bonsai/bim/module/classification/ui.py +++ b/src/bonsai/bonsai/bim/module/classification/ui.py @@ -252,18 +252,34 @@ class ReferenceUI: def draw_reference_ui(self, reference: dict[str, Any]) -> None: row = self.layout.row(align=True) + + split = row.split(factor=0.3) + col1 = split.column() + split = split.split(factor=0.3) + col2 = split.column() + split = split.split(factor=0.7) + col3 = split.column() + col4 = split.column() + + if reference.get("ClassificationSystemName"): + col1.label(text=reference["ClassificationSystemName"], icon="OUTLINER_COLLECTION") + else: + col1.label(text="") + if self.file.schema == "IFC2X3": name = reference["ItemReference"] or "No Identification" else: name = reference["Identification"] or "No Identification" - row.label(text=name, icon="ASSET_MANAGER") - row.label(text=reference["Name"] or "") + col2.label(text=name, icon="ASSET_MANAGER") + col3.label(text=reference["Name"] or "") + + button_row = col4.row(align=True) if reference["Location"]: - row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] + button_row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] if not self.props.active_reference_id: - op = row.operator("bim.enable_editing_classification_reference", text="", icon="GREASEPENCIL") + op = button_row.operator("bim.enable_editing_classification_reference", text="", icon="GREASEPENCIL") op.reference = reference["id"] - op = row.operator("bim.remove_classification_reference", text="", icon="X") + op = button_row.operator("bim.remove_classification_reference", text="", icon="X") op.reference = reference["id"] op.obj = self.obj op.obj_type = self.data.obj_type From a4743b5e0420231e3993b26ad92035f60ed19c2d Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Mon, 29 Sep 2025 17:26:41 +0200 Subject: [PATCH 2/5] refactor using row in uy and util.classification.get_classifiation(reference) --- .../bonsai/bim/module/classification/data.py | 12 +------ .../bonsai/bim/module/classification/ui.py | 33 +++++++++---------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/classification/data.py b/src/bonsai/bonsai/bim/module/classification/data.py index c3a54aa372..a1fa3a6d58 100644 --- a/src/bonsai/bonsai/bim/module/classification/data.py +++ b/src/bonsai/bonsai/bim/module/classification/data.py @@ -104,17 +104,7 @@ class ReferencesData: if element: for reference in ifcopenshell.util.classification.get_references(element): data = reference.get_info() - - if reference.ReferencedSource: - if reference.ReferencedSource.is_a("IfcClassification"): - data["ClassificationSystemName"] = reference.ReferencedSource.Name - elif reference.ReferencedSource.is_a("IfcClassificationReference"): - current = reference.ReferencedSource - while current.ReferencedSource and current.ReferencedSource.is_a("IfcClassificationReference"): - current = current.ReferencedSource - if current.ReferencedSource and current.ReferencedSource.is_a("IfcClassification"): - data["ClassificationSystemName"] = current.ReferencedSource.Name - + data["ifcClassificationReference"] = reference del data["ReferencedSource"] results.append(data) return results diff --git a/src/bonsai/bonsai/bim/module/classification/ui.py b/src/bonsai/bonsai/bim/module/classification/ui.py index acd27803b2..14223274f0 100644 --- a/src/bonsai/bonsai/bim/module/classification/ui.py +++ b/src/bonsai/bonsai/bim/module/classification/ui.py @@ -21,6 +21,8 @@ import bpy import bonsai.bim.helper import bonsai.tool as tool import bonsai.bim.module.classification.prop as classification_prop +import ifcopenshell.util.classification + from bpy.types import Panel, UIList from bonsai.bim.module.classification.data import ( ClassificationsData, @@ -253,33 +255,28 @@ class ReferenceUI: def draw_reference_ui(self, reference: dict[str, Any]) -> None: row = self.layout.row(align=True) - split = row.split(factor=0.3) - col1 = split.column() - split = split.split(factor=0.3) - col2 = split.column() - split = split.split(factor=0.7) - col3 = split.column() - col4 = split.column() - - if reference.get("ClassificationSystemName"): - col1.label(text=reference["ClassificationSystemName"], icon="OUTLINER_COLLECTION") - else: - col1.label(text="") + classification_entity = ifcopenshell.util.classification.get_classification( + reference["ifcClassificationReference"] + ) + classification_name = classification_entity.Name if classification_entity else "" + row.label(text=classification_name, icon="OUTLINER_COLLECTION") if self.file.schema == "IFC2X3": name = reference["ItemReference"] or "No Identification" else: name = reference["Identification"] or "No Identification" - col2.label(text=name, icon="ASSET_MANAGER") - col3.label(text=reference["Name"] or "") + row.label(text=name, icon="ASSET_MANAGER") - button_row = col4.row(align=True) + # Name + row.label(text=reference.get("Name") or "") + + # Buttons if reference["Location"]: - button_row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] + row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] if not self.props.active_reference_id: - op = button_row.operator("bim.enable_editing_classification_reference", text="", icon="GREASEPENCIL") + op = row.operator("bim.enable_editing_classification_reference", text="", icon="GREASEPENCIL") op.reference = reference["id"] - op = button_row.operator("bim.remove_classification_reference", text="", icon="X") + op = row.operator("bim.remove_classification_reference", text="", icon="X") op.reference = reference["id"] op.obj = self.obj op.obj_type = self.data.obj_type From c3c63370bacc47a63c44b74c616892064b257317 Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Mon, 29 Sep 2025 17:42:20 +0200 Subject: [PATCH 3/5] sort rows black formatting --- src/bonsai/bonsai/bim/module/classification/ui.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/classification/ui.py b/src/bonsai/bonsai/bim/module/classification/ui.py index 14223274f0..abb915ef13 100644 --- a/src/bonsai/bonsai/bim/module/classification/ui.py +++ b/src/bonsai/bonsai/bim/module/classification/ui.py @@ -154,7 +154,15 @@ class ReferenceUI: row = self.layout.row(align=True) row.label(text="No References") - for reference in self.data.data["references"]: + def get_classification_name(reference): + classification_entity = ifcopenshell.util.classification.get_classification( + reference["ifcClassificationReference"] + ) + return classification_entity.Name if classification_entity else "" + + sorted_references = sorted(self.data.data["references"], key=get_classification_name) + + for reference in sorted_references: if self.props.active_reference_id == reference["id"]: self.draw_editable_ui() else: @@ -266,11 +274,7 @@ class ReferenceUI: else: name = reference["Identification"] or "No Identification" row.label(text=name, icon="ASSET_MANAGER") - - # Name row.label(text=reference.get("Name") or "") - - # Buttons if reference["Location"]: row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] if not self.props.active_reference_id: From ffc538da8730eecf641442eaf1dc768a68f3b627 Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Mon, 29 Sep 2025 17:45:45 +0200 Subject: [PATCH 4/5] cleanup consistent calling --- src/bonsai/bonsai/bim/module/classification/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bonsai/bonsai/bim/module/classification/ui.py b/src/bonsai/bonsai/bim/module/classification/ui.py index abb915ef13..51ef3dd303 100644 --- a/src/bonsai/bonsai/bim/module/classification/ui.py +++ b/src/bonsai/bonsai/bim/module/classification/ui.py @@ -274,7 +274,7 @@ class ReferenceUI: else: name = reference["Identification"] or "No Identification" row.label(text=name, icon="ASSET_MANAGER") - row.label(text=reference.get("Name") or "") + row.label(text=reference["Name"] or "") if reference["Location"]: row.operator("bim.open_uri", icon="URL", text="").uri = reference["Location"] if not self.props.active_reference_id: From 19b9a55404ecfa7ba0712809fa2e9948846a2e4c Mon Sep 17 00:00:00 2001 From: falken10vdl Date: Sat, 22 Nov 2025 20:12:49 +0100 Subject: [PATCH 5/5] Add posibility to edit classification system name in menu after invoking enable_editing_classification_reference --- .../bonsai/bim/module/classification/operator.py | 10 ++++++++-- src/bonsai/bonsai/bim/module/classification/prop.py | 1 + src/bonsai/bonsai/bim/module/classification/ui.py | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/classification/operator.py b/src/bonsai/bonsai/bim/module/classification/operator.py index 600b86a3d5..a6fd0c6df5 100644 --- a/src/bonsai/bonsai/bim/module/classification/operator.py +++ b/src/bonsai/bonsai/bim/module/classification/operator.py @@ -257,7 +257,9 @@ class EnableEditingClassificationReference(bpy.types.Operator): def execute(self, context): props = tool.Classification.get_classification_reference_props() props.reference_attributes.clear() - bonsai.bim.helper.import_attributes(tool.Ifc.get().by_id(self.reference), props.reference_attributes) + ifc_reference = tool.Ifc.get().by_id(self.reference) + bonsai.bim.helper.import_attributes(ifc_reference, props.reference_attributes) + props.classification_system_name = ifc_reference.ReferencedSource.Name or "" props.active_reference_id = self.reference return {"FINISHED"} @@ -324,9 +326,13 @@ class EditClassificationReference(bpy.types.Operator, tool.Ifc.Operator): props = tool.Classification.get_classification_reference_props() attributes = bonsai.bim.helper.export_attributes(props.reference_attributes) ifc_file = tool.Ifc.get() + reference_entity = ifc_file.by_id(props.active_reference_id) + referenced_source = reference_entity.ReferencedSource + if props.classification_system_name: + referenced_source.Name = props.classification_system_name ifcopenshell.api.classification.edit_reference( ifc_file, - reference=ifc_file.by_id(props.active_reference_id), + reference=reference_entity, attributes=attributes, ) bpy.ops.bim.disable_editing_classification_reference() diff --git a/src/bonsai/bonsai/bim/module/classification/prop.py b/src/bonsai/bonsai/bim/module/classification/prop.py index d85e4e8c4e..4e2de0119d 100644 --- a/src/bonsai/bonsai/bim/module/classification/prop.py +++ b/src/bonsai/bonsai/bim/module/classification/prop.py @@ -95,6 +95,7 @@ class BIMClassificationReferenceProperties(PropertyGroup): classifications: EnumProperty(items=get_classifications, name="Classifications") reference_attributes: CollectionProperty(name="Reference Attributes", type=Attribute) active_reference_id: IntProperty(name="Active Reference Id") + classification_system_name: StringProperty(name="Classification System Name") if TYPE_CHECKING: is_adding: bool diff --git a/src/bonsai/bonsai/bim/module/classification/ui.py b/src/bonsai/bonsai/bim/module/classification/ui.py index 51ef3dd303..077f97553f 100644 --- a/src/bonsai/bonsai/bim/module/classification/ui.py +++ b/src/bonsai/bonsai/bim/module/classification/ui.py @@ -258,6 +258,9 @@ class ReferenceUI: row = self.layout.row(align=True) row.operator("bim.edit_classification_reference", text="Save changes", icon="CHECKMARK") row.operator("bim.disable_editing_classification_reference", text="", icon="CANCEL") + row = self.layout.row() + row.prop(self.props, "classification_system_name", text="Classification System Name") + bonsai.bim.helper.draw_attributes(self.props.reference_attributes, self.layout) def draw_reference_ui(self, reference: dict[str, Any]) -> None: