Files
2026-03-17 14:30:01 -06:00

263 lines
6.6 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
# type: ignore
from __future__ import annotations
from collections.abc import Iterable
import bpy
from bpy.props import (
BoolProperty,
CollectionProperty,
EnumProperty,
FloatProperty,
IntProperty,
PointerProperty,
StringProperty,
)
from bpy.types import Context, PropertyGroup, Scene
from bpy.utils import register_class, unregister_class
from .constants import ID_TYPES, get_id_type
def get_items(
id_types: Iterable[str],
reverse: bool = False,
) -> tuple[tuple[str, str, str, str, int]]:
items = []
for i, id_type in enumerate(id_types):
val = ID_TYPES[id_type]
items.append((id_type, val.label.title(), "", val.icon, i))
if reverse:
items.reverse()
return tuple(items)
def add_parent_item(self: DBU_PG_UserMapSettings, context: Context) -> None:
id_name = self.id_name
if not id_name:
return
parents = self.parents
bl_data = ID_TYPES[self.id_type].collection
id_type = get_id_type(bl_data[id_name])
if id_name in parents:
if any((p.name, p.id_type) == (id_name, id_type) for p in parents):
self.id_name = ""
return
parent = parents.add()
parent.name = id_name
parent.id_type = id_type
self.id_name = ""
update_user_map(self, context)
def update_similar(self: DBU_PG_FindSimilarSettings, context: Context) -> None:
settings = context.scene.dbu_similar_settings
if settings.enabled:
bpy.ops.scene.dbu_find_similar_and_duplicates()
def update_user_map(self: DBU_PG_UserMapSettings, context: Context) -> None:
settings = context.scene.dbu_users_settings
if settings.parent_map:
bpy.ops.scene.dbu_user_map()
class DBU_PG_Item(PropertyGroup):
pass
class DBU_PG_GroupItem(PropertyGroup):
group: CollectionProperty(type=DBU_PG_Item)
id_type: StringProperty()
score: FloatProperty()
class DBU_PG_UserItem(PropertyGroup):
id_type: StringProperty()
node_names: CollectionProperty(type=DBU_PG_Item)
as_parent_idx: IntProperty()
class DBU_PG_ParentItem(PropertyGroup):
id_type: StringProperty()
users: CollectionProperty(type=DBU_PG_UserItem)
class DBU_PG_FindSimilarSettings(PropertyGroup):
id_type: EnumProperty(
items=get_items(('NODETREE', 'MATERIAL', 'LIGHT', 'IMAGE', 'MESH')),
name="Type",
description="Data-block type",
default='NODETREE',
options=set(),
update=update_similar)
similarity_threshold: FloatProperty(
name="Similarity Threshold",
description="Threshold at which two items are considered similar",
default=0.8,
min=0.5,
max=1,
step=1,
options=set(),
update=update_similar)
grouping_threshold: FloatProperty(
name="Grouping Threshold",
description=
"Collections above this similarity threshold, when displayed in the results, are grouped together if they share items. One to disable",
default=0.82,
min=0.5,
max=1,
step=1,
options=set(),
update=update_similar)
exclude_unused: BoolProperty(
name="Unused Nodes",
description="Exclude nodes that are muted or not used by any group outputs",
default=True,
options=set(),
update=update_similar)
exclude_organization: BoolProperty(
name="Frames and Reroutes",
description="Exclude frame and reroute nodes",
default=True,
options=set(),
update=update_similar)
select_object_users: BoolProperty(
name="Select Object Users",
description=
"Object users will be selected when clicking on a data-block (in addition to revealing it in the shader editor)",
options=set())
unhidden_objects: CollectionProperty(type=DBU_PG_Item)
duplicates: CollectionProperty(type=DBU_PG_GroupItem)
scored: CollectionProperty(type=DBU_PG_GroupItem)
enabled: BoolProperty()
class DBU_PG_UserMapSettings(PropertyGroup):
SCENE: BoolProperty(
name="Scenes",
description="Show scenes",
default=False,
options=set(),
update=update_user_map)
MATERIAL: BoolProperty(
name="Materials",
description="Show materials",
default=True,
options=set(),
update=update_user_map)
NODETREE: BoolProperty(
name="Node Groups",
description="Show node groups",
default=True,
options=set(),
update=update_user_map)
OBJECT: BoolProperty(
name="Objects",
description="Show objects",
default=True,
options=set(),
update=update_user_map)
object_contents: BoolProperty(
name="Object Contents",
description="Show the contents of object elements",
default=False,
options=set(),
update=update_user_map)
MESH: BoolProperty(
name="Meshes",
description="Show mesh objects",
default=True,
options=set(),
update=update_user_map)
LIGHT: BoolProperty(
name="Lights",
description="Show light objects",
default=True,
options=set(),
update=update_user_map)
others: BoolProperty(
name="Others",
description="Show curves, metaballs, textures, ...",
default=True,
options=set(),
update=update_user_map)
hide: BoolProperty(name="Hide", description="Hide the list")
parents: CollectionProperty(type=DBU_PG_ParentItem)
id_type: EnumProperty(
items=get_items(('MATERIAL', 'NODETREE', 'IMAGE', 'MESH', 'OBJECT'), reverse=True),
name="Type",
description="Data-block type",
default='MATERIAL',
options=set())
id_name: StringProperty(
name="Search",
description="Search for data-blocks and add them to the list",
update=add_parent_item)
select_object_users: BoolProperty(
name="Select Object Users",
description=
"When clicking on a data-block, select its object users (in addition to revealing it in the node editor)",
options=set())
unhidden_objects: CollectionProperty(type=DBU_PG_Item)
parent_map: CollectionProperty(type=DBU_PG_ParentItem)
user_map: CollectionProperty(type=DBU_PG_ParentItem)
classes = (
DBU_PG_Item,
DBU_PG_GroupItem,
DBU_PG_FindSimilarSettings,
DBU_PG_UserItem,
DBU_PG_ParentItem,
DBU_PG_UserMapSettings,
)
def register() -> None:
for cls in classes:
register_class(cls)
Scene.dbu_similar_settings = PointerProperty(type=DBU_PG_FindSimilarSettings)
Scene.dbu_users_settings = PointerProperty(type=DBU_PG_UserMapSettings)
def unregister() -> None:
del Scene.dbu_users_settings
del Scene.dbu_similar_settings
for cls in reversed(classes):
unregister_class(cls)