Skip to content

Bonsai: Update Current Style no longer reloads external .blend styles (regression from #8342) #9477

Description

@theoryshaw

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

  1. 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.
  2. Change that material in the .blend file and save it.
  3. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BonsaiPR ProposedA PR has been proposed for this bug/feature.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions