Problem
The refresh button next to the style type dropdown in the Styles panel (bim.update_current_style, Update Current Style) no longer picks up changes made to an external .blend style. After editing and saving the material in the referenced .blend, clicking the button (or SHIFT+CLICK to update all styles) leaves the old material in the model.
This button was added in 6a2bbfa for #3293 ("Option to batch-reload all external IFC styles"), so reloading is its purpose.
Steps to reproduce
- Have an
IfcSurfaceStyle with an IfcExternallyDefinedSurfaceStyle whose Location points to a material in a .blend file, loaded so the material is in External (Pretty) mode.
- Change that material in the
.blend file and save it.
- In Bonsai, select an object that uses the style and click Update Current Style in the Styles panel.
Expected: the material is re-appended from the .blend and shows the changes.
Actual: nothing changes.
Cause
#8342 (c9f991a) introduced dual-branch materials: the external node graph is copied into the material once, next to a flat branch, with outputs BIM_Output_External and BIM_Output_Flat. For those materials, Style.switch_shading() now just toggles which output is active and returns:
|
def switch_shading(cls, blender_material: bpy.types.Material, style_type: StyleType) -> None: |
|
if style_type == "External": |
|
ext, fast = cls.get_branch_outputs(blender_material) |
|
if ext and fast: |
|
ext.is_active_output = True |
|
fast.is_active_output = False |
|
blender_material.update_tag() |
|
return |
UpdateCurrentStyle only sets active_style_type on each material, whose update callback ends in switch_shading():
|
class UpdateCurrentStyle(bpy.types.Operator): |
|
bl_idname = "bim.update_current_style" |
|
bl_label = "Update Current Style" |
|
bl_description = ( |
|
"Update style for all selected objects according to current style type\n(Shading/External).\n\n" |
|
+ "SHIFT+CLICK to update ALL styles in the .ifc file to current style type" |
|
) |
|
bl_options = {"REGISTER", "UNDO"} |
|
update_all: bpy.props.BoolProperty(name="Update All", default=False, options={"SKIP_SAVE"}) |
|
style_id: bpy.props.IntProperty(default=0, options={"SKIP_SAVE"}) |
|
|
|
def invoke(self, context, event): |
|
# updating all styles on shift+click |
|
# make sure to use SKIP_SAVE on property, otherwise it might get stuck |
|
if event.type == "LEFTMOUSE" and event.shift: |
|
self.update_all = True |
|
return self.execute(context) |
|
|
|
def execute(self, context): |
|
style = tool.Ifc.get().by_id(self.style_id) |
|
material = tool.Ifc.get_object(style) |
|
msprops = tool.Style.get_material_style_props(material) |
|
current_style_type = msprops.active_style_type |
|
|
|
if self.update_all: |
|
sprops = tool.Style.get_style_props() |
|
sprops.active_style_type = current_style_type |
|
return {"FINISHED"} |
|
|
|
updated_materials: set[bpy.types.Material] = set() |
|
for obj in context.selected_objects: |
|
if not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve)): |
|
continue |
|
for mat in obj.data.materials: |
|
if not mat: |
|
continue |
|
msprops_ = tool.Style.get_material_style_props(mat) |
|
if msprops_.ifc_definition_id == 0: |
|
continue |
|
if mat in updated_materials: |
|
continue |
|
msprops_.active_style_type = current_style_type |
|
updated_materials.add(mat) |
|
return {"FINISHED"} |
So bim.activate_external_style, the only code path that re-appends the material from the .blend, is never reached. Before #8342, switch_shading("External") always called bim.activate_external_style, which is why the button used to reload the style.
Trace from temporary debug prints, clicking the button on a wall whose materials were already External:
mat 'GS_Red Hollow Clay Blocks' (#4086400): 'External' -> 'External'
update_shading_style: has_blender_external_style=True Location='../../../../OD_Submodules/OD_Textures/Materials.blend'
switch_shading: branch outputs: ext='BIM_Output_External' fast='BIM_Output_Flat'
-> dual-branch: activated BIM_Output_External
Affects v0.9.0 (checked at 23f3874) and v0.8.0.
Proposed fix
Keep the fast path in switch_shading(): viewport shading changes and the Flat/Pretty toggle set active_style_type on every material and shouldn't read from disk. In UpdateCurrentStyle, when the style type is External, call bim.activate_external_style for each updated material, and for all IFC materials on SHIFT+CLICK. For dual-branch materials this goes through Style.update_external_branch(), which replaces only the external branch and leaves the flat branch alone. PR to follow.
Problem
The refresh button next to the style type dropdown in the Styles panel (
bim.update_current_style, Update Current Style) no longer picks up changes made to an external.blendstyle. After editing and saving the material in the referenced.blend, clicking the button (or SHIFT+CLICK to update all styles) leaves the old material in the model.This button was added in 6a2bbfa for #3293 ("Option to batch-reload all external IFC styles"), so reloading is its purpose.
Steps to reproduce
IfcSurfaceStylewith anIfcExternallyDefinedSurfaceStylewhoseLocationpoints to a material in a.blendfile, loaded so the material is in External (Pretty) mode..blendfile and save it.Expected: the material is re-appended from the
.blendand shows the changes.Actual: nothing changes.
Cause
#8342 (c9f991a) introduced dual-branch materials: the external node graph is copied into the material once, next to a flat branch, with outputs
BIM_Output_ExternalandBIM_Output_Flat. For those materials,Style.switch_shading()now just toggles which output is active and returns:IfcOpenShell/src/bonsai/bonsai/tool/style.py
Lines 977 to 984 in 23f3874
UpdateCurrentStyleonly setsactive_style_typeon each material, whose update callback ends inswitch_shading():IfcOpenShell/src/bonsai/bonsai/bim/module/style/operator.py
Lines 208 to 251 in 23f3874
So
bim.activate_external_style, the only code path that re-appends the material from the.blend, is never reached. Before #8342,switch_shading("External")always calledbim.activate_external_style, which is why the button used to reload the style.Trace from temporary debug prints, clicking the button on a wall whose materials were already External:
Affects
v0.9.0(checked at 23f3874) andv0.8.0.Proposed fix
Keep the fast path in
switch_shading(): viewport shading changes and the Flat/Pretty toggle setactive_style_typeon every material and shouldn't read from disk. InUpdateCurrentStyle, when the style type is External, callbim.activate_external_stylefor each updated material, and for all IFC materials on SHIFT+CLICK. For dual-branch materials this goes throughStyle.update_external_branch(), which replaces only the external branch and leaves the flat branch alone. PR to follow.