From d1c4b39e17bc98ed6608cb7474e1f4627ab6d8df Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Tue, 21 Jul 2026 15:54:59 +0300 Subject: [PATCH] Bonsai: right-click rename on a material name (#6680) Adds a "Rename Material" entry to the context menu that already extends every button in the properties editor (UI_MT_button_context_menu), triggered when right-clicking a material name button (bim.select_by_material) that points to a real IfcMaterial. This gives a quick entry point to renaming from the Object Material panel without navigating to the scene Materials list. This follows the pattern that #6680's thread converged on: theoryshaw requested a right-click entry (rather than a pencil icon or double-click) that keeps the existing single-click select-by-material behaviour intact. falken10vdl is the issue's assignee; this is offered as a starting point for that discussion, not a replacement for it. Generated with the assistance of an AI coding tool. (cherry picked from commit 8c667b8ae052b29a0b18df9d5d5bef99e387c6f5) --- .../bonsai/bim/module/material/__init__.py | 1 + .../bonsai/bim/module/material/operator.py | 20 +++++++++++++++++++ src/bonsai/bonsai/bim/ui.py | 16 +++++++++++++++ src/bonsai/bonsai/core/material.py | 8 ++++++++ 4 files changed, 45 insertions(+) diff --git a/src/bonsai/bonsai/bim/module/material/__init__.py b/src/bonsai/bonsai/bim/module/material/__init__.py index 5f14b170ee..50afbd4dff 100644 --- a/src/bonsai/bonsai/bim/module/material/__init__.py +++ b/src/bonsai/bonsai/bim/module/material/__init__.py @@ -56,6 +56,7 @@ classes = ( operator.RemoveMaterial, operator.RemoveMaterialSet, operator.RemoveProfile, + operator.RenameMaterial, operator.ReorderMaterialSetItem, operator.SelectByMaterial, operator.SelectMaterialInMaterialsUI, diff --git a/src/bonsai/bonsai/bim/module/material/operator.py b/src/bonsai/bonsai/bim/module/material/operator.py index 6ec1ccf188..b2ab1cfa06 100644 --- a/src/bonsai/bonsai/bim/module/material/operator.py +++ b/src/bonsai/bonsai/bim/module/material/operator.py @@ -102,6 +102,26 @@ class EditMaterial(bpy.types.Operator, tool.Ifc.Operator): core.edit_material(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material)) +class RenameMaterial(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.rename_material" + bl_label = "Rename Material" + bl_description = "Rename an IfcMaterial" + bl_options = {"REGISTER", "UNDO"} + material: bpy.props.IntProperty() + name: bpy.props.StringProperty(name="Name") + + def invoke(self, context, event): + material = tool.Ifc.get().by_id(self.material) + self.name = material.Name or "" + return context.window_manager.invoke_props_dialog(self) + + def draw(self, context): + self.layout.prop(self, "name") + + def _execute(self, context): + core.rename_material(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material), name=self.name) + + class DisableEditingMaterial(bpy.types.Operator): bl_idname = "bim.disable_editing_material" bl_label = "Disable Editing Material" diff --git a/src/bonsai/bonsai/bim/ui.py b/src/bonsai/bonsai/bim/ui.py index 412e3aa16a..fa4aad402e 100644 --- a/src/bonsai/bonsai/bim/ui.py +++ b/src/bonsai/bonsai/bim/ui.py @@ -41,6 +41,7 @@ import bonsai.bim.helper import bonsai.tool as tool from bonsai.bim.ifc import is_cache_locked_by_other_process from bonsai.bim.module.bsdd.prop import BIMBSDDProperties, BSDDProperty +from bonsai.bim.module.material.operator import SelectByMaterial from bonsai.bim.module.model import prop as _model_prop from bonsai.bim.module.model import ui as _model_ui from bonsai.bim.module.pset.prop import IfcProperty @@ -1844,6 +1845,21 @@ def draw_statusbar(self, context): def draw_custom_context_menu(self: bpy.types.Menu, context: bpy.types.Context) -> None: # https://blender.stackexchange.com/a/275555/86891 + + # Context menu for material name buttons (e.g. `bim.select_by_material`), + # offering a quick "Rename Material" entry instead of having to look up + # the material in the scene Materials panel to rename it. + button_operator = getattr(context, "button_operator", None) + if button_operator is not None and button_operator.bl_rna.identifier == SelectByMaterial.bl_rna.identifier: + ifc_file = tool.Ifc.get() + material = ifc_file.by_id(button_operator.material) if ifc_file else None + if material is not None and material.is_a("IfcMaterial"): + assert self.layout + self.layout.separator() + op = self.layout.operator("bim.rename_material", text="Rename Material", icon="GREASEPENCIL") + op.material = material.id() + return + if ( not hasattr(context, "button_pointer") or not hasattr(context, "button_prop") diff --git a/src/bonsai/bonsai/core/material.py b/src/bonsai/bonsai/core/material.py index 0a08f5e0bf..00dbd8e178 100644 --- a/src/bonsai/bonsai/core/material.py +++ b/src/bonsai/bonsai/core/material.py @@ -107,6 +107,14 @@ def disable_editing_material(material_tool: type[tool.Material]) -> None: material_tool.disable_editing_material() +def rename_material( + ifc: type[tool.Ifc], material_tool: type[tool.Material], material: ifcopenshell.entity_instance, name: str +) -> None: + ifc.run("material.edit_material", material=material, attributes={"Name": name}) + if material_tool.is_editing_materials(): + material_tool.import_material_definitions(material_tool.get_active_material_type()) + + def assign_material( ifc: type[tool.Ifc], material_tool: type[tool.Material],