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 95f7a2bcde
commit c462fc9337
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 blenderbim.bim.module.model.workspace import LIST_OF_TOOLS, TOOLS_TO_CLASSES_MAP
from mathutils import Vector from mathutils import Vector
from math import cos, degrees from math import cos, degrees
from typing import Union
cwd = os.path.dirname(os.path.realpath(__file__)) cwd = os.path.dirname(os.path.realpath(__file__))
@@ -286,26 +287,7 @@ def get_override_scene_panel(panel_name):
return override_panel return override_panel
# TODO: possibly override scene panels from other addons too? OVERRIDE_SCENE_PANELS = tool.Blender.get_scene_panels_list()
# 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",)
@persistent @persistent
+55
View File
@@ -875,3 +875,58 @@ class Blender(blenderbim.core.tool.Blender):
bpy.utils.unregister_tool(ws_covering.CoveringTool) bpy.utils.unregister_tool(ws_covering.CoveringTool)
except: except:
pass 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 ifcopenshell
import blenderbim.core.tool import blenderbim.core.tool
import blenderbim.tool as tool import blenderbim.tool as tool
import pytest
from test.bim.bootstrap import NewFile from test.bim.bootstrap import NewFile
from blenderbim.tool.blender import Blender as subject from blenderbim.tool.blender import Blender as subject
@@ -44,3 +45,17 @@ class TestCopyNodeGraph(NewFile):
subject.copy_node_graph(material_to, material_from) subject.copy_node_graph(material_to, material_from)
assert len(material_to_nodes) == 2 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"})