move scene panels from different addons to "Blender Properties"

now we also automatically get list of default blender scene panels instead of hardcoding them
This commit is contained in:
Andrej730
2024-04-03 12:00:44 +05:00
parent e8b2ccdd3c
commit c4d437cce4
3 changed files with 72 additions and 20 deletions
+2 -20
View File
@@ -31,6 +31,7 @@ from blenderbim.bim.module.model.data import AuthoringData
from blenderbim.bim.module.model.workspace import LIST_OF_TOOLS, TOOLS_TO_CLASSES_MAP
from mathutils import Vector
from math import cos, degrees
from typing import Union
cwd = os.path.dirname(os.path.realpath(__file__))
@@ -286,26 +287,7 @@ def get_override_scene_panel(panel_name):
return override_panel
# TODO: possibly override scene panels from other addons too?
# list can be updated from
# https://projects.blender.org/blender/blender/src/branch/main/scripts/startup/bl_ui/properties_scene.py#L421
OVERRIDE_SCENE_PANELS = (
"SCENE_PT_scene",
"SCENE_PT_unit",
"SCENE_PT_physics",
"SCENE_PT_rigid_body_world",
"SCENE_PT_rigid_body_world_settings",
"SCENE_PT_rigid_body_cache",
"SCENE_PT_rigid_body_field_weights",
"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",)
OVERRIDE_SCENE_PANELS = tool.Blender.get_scene_panels_list()
@persistent
+55
View File
@@ -875,3 +875,58 @@ class Blender(blenderbim.core.tool.Blender):
bpy.utils.unregister_tool(ws_covering.CoveringTool)
except:
pass
@classmethod
def get_scene_panels_list(cls) -> tuple[str, ...]:
# example default blender scene panels can be found in
# https://projects.blender.org/blender/blender/src/branch/main/scripts/startup/bl_ui/properties_scene.py#L421
scene_panels: list[str] = []
panels_to_parents: dict[str, str] = dict()
for item_name in dir(bpy.types):
item = getattr(bpy.types, item_name)
# filter only panels
if not hasattr(item, "bl_rna") or not isinstance(item.bl_rna, bpy.types.Panel):
continue
# filter scene panels
if getattr(item, "bl_context", None) != "scene":
continue
scene_panels.append(item_name)
parent_panel = getattr(item, "bl_parent_id", None)
if parent_panel is not None:
panels_to_parents[item_name] = parent_panel
scene_panels = cls.sort_panels_for_register(scene_panels, panels_to_parents)
return tuple(scene_panels)
@classmethod
def sort_panels_for_register(cls, items: list[str], items_to_parents: dict[str, str]) -> list[str]:
"""sort panels ensuring parents panels will be registered first
as otherwise we'll get errors unregistering them all and registering child panel"""
final_items = []
unsorted = items.copy()
# first, add items without parents
for item in unsorted[:]:
if item not in items_to_parents:
final_items.append(item)
unsorted.remove(item)
# store children for each parent
children: dict[str, list[str]] = dict()
for item in items_to_parents:
children.setdefault(items_to_parents[item], []).append(item)
# add children recursively, ensuring parents are added first
keep_looking = True
while keep_looking:
keep_looking = False
for item in list(children.keys()):
# check if parent panel was already added
if item not in final_items:
continue
final_items.extend(children[item])
del children[item]
keep_looking = True
assert set(items) == set(final_items), "Sorted list doesn't match original"
return final_items
+15
View File
@@ -20,6 +20,7 @@ import bpy
import ifcopenshell
import blenderbim.core.tool
import blenderbim.tool as tool
import pytest
from test.bim.bootstrap import NewFile
from blenderbim.tool.blender import Blender as subject
@@ -44,3 +45,17 @@ class TestCopyNodeGraph(NewFile):
subject.copy_node_graph(material_to, material_from)
assert len(material_to_nodes) == 2
class TestSortPanelsForRegister(NewFile):
def test_run(self):
items = ["A", "B", "C", "D"]
items_to_parents = {"A": "D", "D": "C", "C": "B"}
sorted_items = subject.sort_panels_for_register(items, items_to_parents)
assert tuple(sorted_items) == ("B", "C", "D", "A")
with pytest.raises(AssertionError):
subject.sort_panels_for_register(items, {"A": "K"})
with pytest.raises(AssertionError):
subject.sort_panels_for_register(items, {"J": "A"})