From 5ce9d21dff3b8504fce843c1ce311cbcbb75792e Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Fri, 20 Sep 2024 21:45:08 +0500 Subject: [PATCH] Purging styles to also purge associated blender materials #3914 --- src/bonsai/bonsai/bim/module/debug/operator.py | 4 +--- src/bonsai/bonsai/core/style.py | 12 ++++++++++-- src/bonsai/bonsai/tool/debug.py | 12 ------------ src/bonsai/bonsai/tool/style.py | 18 ++++++++++++++++++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/debug/operator.py b/src/bonsai/bonsai/bim/module/debug/operator.py index 1aad7b317d..6bb079b073 100644 --- a/src/bonsai/bonsai/bim/module/debug/operator.py +++ b/src/bonsai/bonsai/bim/module/debug/operator.py @@ -648,9 +648,7 @@ class PurgeUnusedObjects(bpy.types.Operator, tool.Ifc.Operator): elif object_type == "PROFILE": purged = bonsai.core.profile.purge_unused_profiles(tool.Ifc, tool.Profile) elif object_type == "STYLE": - # It's okay to remove IfcPresentationStyle if just remove_deep - # as there are no white listed inverses. - purged = tool.Debug.purge_unused_class("IfcPresentationStyle") + purged = tool.Style.purge_unused_styles() elif object_type == "MATERIAL": purged = tool.Material.purge_unused_materials() else: diff --git a/src/bonsai/bonsai/core/style.py b/src/bonsai/bonsai/core/style.py index 347efb4fe0..9d4cd5c9fe 100644 --- a/src/bonsai/bonsai/core/style.py +++ b/src/bonsai/bonsai/core/style.py @@ -55,7 +55,15 @@ def update_external_style( ifc.run("style.edit_surface_style", style=external_style, attributes=attributes) -def remove_style(ifc: tool.Ifc, style_tool: tool.Style, style: ifcopenshell.entity_instance) -> None: +def remove_style( + ifc: tool.Ifc, style_tool: tool.Style, style: ifcopenshell.entity_instance, reload_styles_ui: bool = False +) -> None: + """Remove IfcPresentationStyle and associated Blender material. + + :param reload_styles_ui: Whether to reload Styles UI after removal. + Useful to disable if you plan to remove many styles and want to + avoid unnecessary reloads. + """ obj = ifc.get_object(style) # Get style_type before removing object as later StylesData might fail to load # due object not yet removed completely. @@ -63,7 +71,7 @@ def remove_style(ifc: tool.Ifc, style_tool: tool.Style, style: ifcopenshell.enti ifc.unlink(element=style) ifc.run("style.remove_style", style=style) style_tool.delete_object(obj) - if style_tool.is_editing_styles(): + if reload_styles_ui and style_tool.is_editing_styles(): style_tool.import_presentation_styles(style_type) diff --git a/src/bonsai/bonsai/tool/debug.py b/src/bonsai/bonsai/tool/debug.py index 42380e2ae3..972ea37b08 100644 --- a/src/bonsai/bonsai/tool/debug.py +++ b/src/bonsai/bonsai/tool/debug.py @@ -98,15 +98,3 @@ class Debug(bonsai.core.tool.Debug): print(f"{class_string: <50} {unused[ifc_class]: >5}") return sum(unused.values()) - - @classmethod - def purge_unused_class(cls, ifc_class: str) -> int: - ifc_file = tool.Ifc.get() - elements = ifc_file.by_type(ifc_class) - i = 0 - for element in elements: - if ifc_file.get_total_inverses(element) != 0: - continue - ifcopenshell.util.element.remove_deep(ifc_file, element) - i += 1 - return i diff --git a/src/bonsai/bonsai/tool/style.py b/src/bonsai/bonsai/tool/style.py index 6f1690a7e5..796334756e 100644 --- a/src/bonsai/bonsai/tool/style.py +++ b/src/bonsai/bonsai/tool/style.py @@ -21,6 +21,7 @@ import numpy as np import ifcopenshell import ifcopenshell.util.element import ifcopenshell.util.representation +import bonsai.core.style import bonsai.core.tool import bonsai.tool as tool import bonsai.bim.helper @@ -695,3 +696,20 @@ class Style(bonsai.core.tool.Style): blender_material = tool.Ifc.get_object(style) # Will implicitly update the style name using handler. blender_material.name = name + + @classmethod + def purge_unused_styles(cls) -> int: + """Purge unused styles (and related Blender materials). + + Note that Styles UI should be updated manually after using this method. + """ + + ifc_file = tool.Ifc.get() + elements = ifc_file.by_type("IfcPresentationStyle") + i = 0 + for element in elements: + if ifc_file.get_total_inverses(element) != 0: + continue + bonsai.core.style.remove_style(tool.Ifc, tool.Style, element, reload_styles_ui=False) + i += 1 + return i