From 2520a9305598763d5d286c2d8306bc43bf1dd6d8 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Mon, 11 Dec 2023 16:25:37 +0500 Subject: [PATCH] Fix issues unregistering overridden panels Previously overridden scene panels were removed but original panels were not restored. Also added condition check for Blender version to generate list of panels to override, so we won't miss any errors using `try - except`. --- src/blenderbim/blenderbim/bim/__init__.py | 24 +++-------- src/blenderbim/blenderbim/bim/handler.py | 51 ++++++++++++----------- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/__init__.py b/src/blenderbim/blenderbim/bim/__init__.py index e1b11998c7..4319d3be15 100644 --- a/src/blenderbim/blenderbim/bim/__init__.py +++ b/src/blenderbim/blenderbim/bim/__init__.py @@ -181,6 +181,7 @@ addon_keymaps = [] icons = None is_registering = False last_commit_hash = "8888888" +overridden_scene_panels = dict() def on_register(scene): @@ -285,22 +286,7 @@ def unregister(): km.keymap_items.remove(kmi) addon_keymaps.clear() - for panel in [ - "SCENE_PT_scene", - "SCENE_PT_unit", - "SCENE_PT_physics", - "SCENE_PT_rigid_body_world", - "SCENE_PT_audio", - "SCENE_PT_keying_sets", - "SCENE_PT_simulation", - "SCENE_PT_custom_props", # 4.0 - # after SCENE_PT_keying_sets - "SCENE_PT_keying_set_paths" "SCENE_PT_keyframing_settings", - ]: - try: - bpy.utils.unregister_class(getattr(handler, f"Override_{panel}")) - except: - # NOTE: breaks Blender UI on unregister - # since default Blender panels are unregistered on load_post - # unregistering our override panels removes them from Blender completely - pass + for original_panel, override_panel in tuple(overridden_scene_panels.items()): + bpy.utils.unregister_class(override_panel) + bpy.utils.register_class(original_panel) + del overridden_scene_panels[original_panel] diff --git a/src/blenderbim/blenderbim/bim/handler.py b/src/blenderbim/blenderbim/bim/handler.py index 32a1f2d703..f67a4db228 100644 --- a/src/blenderbim/blenderbim/bim/handler.py +++ b/src/blenderbim/blenderbim/bim/handler.py @@ -21,6 +21,7 @@ import bpy import json import addon_utils import ifcopenshell.api.owner.settings +import blenderbim.bim import blenderbim.tool as tool import blenderbim.core.owner as core_owner from bpy.app.handlers import persistent @@ -259,9 +260,7 @@ def poll_check_blender_tab(cls, context): def get_override_scene_panel(panel_name): - original_panel = getattr(bpy.types, panel_name, None) - if original_panel is None: - return + original_panel = getattr(bpy.types, panel_name) override_panel = type(f"Override_{panel_name}", (original_panel,), {}) override_panel.bl_idname = f"{panel_name}_override" @@ -287,6 +286,22 @@ def get_override_scene_panel(panel_name): return override_panel +OVERRIDE_SCENE_PANELS = ( + "SCENE_PT_scene", + "SCENE_PT_unit", + "SCENE_PT_physics", + "SCENE_PT_rigid_body_world", + "SCENE_PT_audio", + "SCENE_PT_keying_sets", + "SCENE_PT_custom_props", + # after SCENE_PT_keying_sets + "SCENE_PT_keying_set_paths", + "SCENE_PT_keyframing_settings", +) +if bpy.app.version >= (4, 0): + OVERRIDE_SCENE_PANELS += ("SCENE_PT_simulation",) + + @persistent def load_post(scene): global global_subscription_owner @@ -325,28 +340,14 @@ def load_post(scene): # To improve usability for new users, we hijack the scene properties # tab. We override default scene properties panels with our own poll # to hide them unless the user has chosen to view Blender properties. - for panel in [ - "SCENE_PT_scene", - "SCENE_PT_unit", - "SCENE_PT_physics", - "SCENE_PT_rigid_body_world", - "SCENE_PT_audio", - "SCENE_PT_keying_sets", - "SCENE_PT_simulation", # 4.0+ - "SCENE_PT_custom_props", - # after SCENE_PT_keying_sets - "SCENE_PT_keying_set_paths", - "SCENE_PT_keyframing_settings", - ]: - try: - override_panel = get_override_scene_panel(panel) - if override_panel is None: - continue - original_panel = getattr(bpy.types, panel) - bpy.utils.register_class(override_panel) - bpy.utils.unregister_class(original_panel) - except Exception: # some panels belong to different Blender versions - pass + for panel in OVERRIDE_SCENE_PANELS: + override_panel = get_override_scene_panel(panel) + if override_panel is None: + continue + original_panel = getattr(bpy.types, panel) + bpy.utils.register_class(override_panel) + bpy.utils.unregister_class(original_panel) + blenderbim.bim.overridden_scene_panels[original_panel] = override_panel # https://blender.stackexchange.com/questions/140644/how-can-make-the-state-of-a-boolean-property-relative-to-the-3d-view-area for screen in bpy.data.screens: if len(screen.BIMAreaProperties) == 20: