diff --git a/src/bonsai/bonsai/bim/module/boundary/__init__.py b/src/bonsai/bonsai/bim/module/boundary/__init__.py index fe11440adc..aff548d785 100644 --- a/src/bonsai/bonsai/bim/module/boundary/__init__.py +++ b/src/bonsai/bonsai/bim/module/boundary/__init__.py @@ -23,6 +23,7 @@ from . import operator, prop, ui classes = ( operator.AddBoundary, operator.ColourByRelatedBuildingElement, + operator.CopyBoundaryAttributeToSelection, operator.DecorateBoundaries, operator.DisableEditingBoundary, operator.DisableEditingBoundaryGeometry, diff --git a/src/bonsai/bonsai/bim/module/boundary/operator.py b/src/bonsai/bonsai/bim/module/boundary/operator.py index d159e4379e..8a99f0f6c1 100644 --- a/src/bonsai/bonsai/bim/module/boundary/operator.py +++ b/src/bonsai/bonsai/bim/module/boundary/operator.py @@ -39,6 +39,7 @@ from ifcopenshell.util.shape_builder import ShapeBuilder from mathutils import Matrix, Vector import bonsai.bim.import_ifc as import_ifc +import bonsai.core.attribute as core import bonsai.core.geometry import bonsai.tool as tool from bonsai.bim.ifc import IfcStore @@ -422,6 +423,32 @@ class EditBoundaryAttributes(bpy.types.Operator, tool.Ifc.Operator): return {"FINISHED"} +class CopyBoundaryAttributeToSelection(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.copy_boundary_attribute_to_selection" + bl_label = "Copy Boundary Attribute To Selection" + bl_options = {"REGISTER", "UNDO"} + name: bpy.props.StringProperty() + + def _execute(self, context): + obj = tool.Blender.get_active_object() + assert obj + bprops = tool.Boundary.get_object_boundary_props(obj) + if self.name in EDITABLE_ATTRIBUTES: + blender_prop = EDITABLE_ATTRIBUTES[self.name] + blender_obj = getattr(bprops, blender_prop, None) + value = tool.Ifc.get_entity(blender_obj) if blender_obj else None + elif self.name == "PhysicalOrVirtualBoundary": + value = bprops.physical_or_virtual + elif self.name == "InternalOrExternalBoundary": + value = bprops.internal_or_external + else: + return + total = core.copy_attribute_to_selection( + tool.Ifc, tool.Blender, tool.Root, tool.Spatial, name=self.name, value=value + ) + self.report({"INFO"}, f"Attribute was successfully copied to {total} elements.") + + class UpdateBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.update_boundary_geometry" bl_label = "Update Boundary Geometry" diff --git a/src/bonsai/bonsai/bim/module/boundary/ui.py b/src/bonsai/bonsai/bim/module/boundary/ui.py index 91990a5eb0..5558b6a7da 100644 --- a/src/bonsai/bonsai/bim/module/boundary/ui.py +++ b/src/bonsai/bonsai/bim/module/boundary/ui.py @@ -77,10 +77,14 @@ class BIM_PT_Boundary(Panel): self.draw_relation_editor(boundary, "RelatedBuildingElement", "related_building_element") self.draw_relation_editor(boundary, "ParentBoundary", "parent_boundary") self.draw_relation_editor(boundary, "CorrespondingBoundary", "corresponding_boundary") - row = self.layout.row() + row = self.layout.row(align=True) row.prop(self.bprops, "physical_or_virtual") - row = self.layout.row() + op = row.operator("bim.copy_boundary_attribute_to_selection", text="", icon="COPYDOWN") + op.name = "PhysicalOrVirtualBoundary" + row = self.layout.row(align=True) row.prop(self.bprops, "internal_or_external") + op = row.operator("bim.copy_boundary_attribute_to_selection", text="", icon="COPYDOWN") + op.name = "InternalOrExternalBoundary" else: row = self.layout.row() row.operator("bim.enable_editing_boundary", icon="GREASEPENCIL", text="Edit") @@ -125,6 +129,8 @@ class BIM_PT_Boundary(Panel): if hasattr(boundary, ifc_attribute): row = self.layout.row(align=True) row.prop(self.bprops, blender_property) + op = row.operator("bim.copy_boundary_attribute_to_selection", text="", icon="COPYDOWN") + op.name = ifc_attribute class BIM_PT_SpaceBoundaries(Panel): diff --git a/src/bonsai/bonsai/core/attribute.py b/src/bonsai/bonsai/core/attribute.py index 803cc353bf..607f669bb2 100644 --- a/src/bonsai/bonsai/core/attribute.py +++ b/src/bonsai/bonsai/core/attribute.py @@ -18,7 +18,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: @@ -31,7 +31,7 @@ def copy_attribute_to_selection( root: type[tool.Root], spatial: type[tool.Spatial], name: str, - value: Union[str, None], + value: Any, ) -> int: total_changed = 0 has_edited_spatial_name = False