Bonsai: refresh material data unconditionally instead of forcing a redraw

falken10vdl reviewed 16b1b4e7b1 on #8843 and pointed out that tagging
every area for redraw was overkill. The actual problem was that the
Object Material panel and the scene Materials list read from plain
python caches (ObjectMaterialData and MaterialsData) that only get
invalidated when the Materials editing UI list is reloaded, which
never happens while you are not in editing mode. The redraw itself was
never the issue, closing the rename dialog already triggers one.

Removed the tag_redraw loop from RenameMaterial and instead call the
existing bonsai.bim.module.material.data.refresh() function from
core.rename_material, unconditionally, through a new tool.Material.refresh()
method. This is the same invalidate-on-next-load mechanism already used
by every other module's Data classes, just wired up for this operator
too, instead of introducing a new one.

Also updates the core tests to prescribe the new unconditional refresh()
call, and adds tool-layer coverage for tool.Material.refresh().

Generated with the assistance of an AI coding tool.
This commit is contained in:
Petru Conduraru
2026-07-21 21:08:21 +03:00
parent 16b1b4e7b1
commit 7ab0628c54
6 changed files with 21 additions and 3 deletions
@@ -120,9 +120,6 @@ class RenameMaterial(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context):
core.rename_material(tool.Ifc, tool.Material, material=tool.Ifc.get().by_id(self.material), name=self.name)
if screen := context.screen:
for area in screen.areas:
area.tag_redraw()
class DisableEditingMaterial(bpy.types.Operator):
+1
View File
@@ -113,6 +113,7 @@ def rename_material(
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())
material_tool.refresh()
def assign_material(
+1
View File
@@ -667,6 +667,7 @@ class Material:
def is_editing_materials(cls): pass
def is_material_used_in_sets(cls, material): pass
def load_material_attributes(cls, material): pass
def refresh(cls): pass
def replace_material_with_material_profile(cls, element): pass
def update_elements_using_material(cls, material): pass
+6
View File
@@ -146,6 +146,12 @@ class Material(bonsai.core.tool.Material):
MaterialsData.data["material_styles_data"] = MaterialsData.material_styles_data()
@classmethod
def refresh(cls) -> None:
from bonsai.bim.module.material.data import refresh as refresh_material_data
refresh_material_data()
@classmethod
def is_editing_materials(cls) -> bool:
props = tool.Material.get_material_props()
+2
View File
@@ -97,6 +97,7 @@ class TestRenameMaterial:
def test_renaming_a_material(self, ifc, material):
ifc.run("material.edit_material", material="material", attributes={"Name": "name"}).should_be_called()
material.is_editing_materials().should_be_called().will_return(False)
material.refresh().should_be_called()
subject.rename_material(ifc, material, material="material", name="name")
def test_renaming_a_material_and_reloading_imported_materials(self, ifc, material):
@@ -104,6 +105,7 @@ class TestRenameMaterial:
material.is_editing_materials().should_be_called().will_return(True)
material.get_active_material_type().should_be_called().will_return("material_type")
material.import_material_definitions("material_type").should_be_called()
material.refresh().should_be_called()
subject.rename_material(ifc, material, material="material", name="name")
+11
View File
@@ -139,6 +139,17 @@ class TestImportMaterialDefinitions(NewFile):
assert props.materials[0].total_elements == 0
class TestRefresh(NewFile):
def test_run(self):
from bonsai.bim.module.material.data import MaterialsData, ObjectMaterialData
MaterialsData.is_loaded = True
ObjectMaterialData.is_loaded = True
subject.refresh()
assert MaterialsData.is_loaded is False
assert ObjectMaterialData.is_loaded is False
class TestIsEditingMaterials(NewFile):
def test_run(self):
props = tool.Material.get_material_props()