Files
blender-portable-repo/extensions/blender_org/datablock_utils/constants.py
T
2026-03-17 14:58:51 -06:00

104 lines
3.4 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
from dataclasses import dataclass
from typing import Any, cast
import bpy
from bpy.types import CollectionProperty, EnumProperty
@dataclass(slots=True)
class IDType:
label: str
icon: str
_collection: str
is_ntree: bool = False
is_object_data: bool = False
@property
def collection(self) -> bpy.types.bpy_prop_collection:
return getattr(bpy.data, self._collection, {}) # type: ignore
def _assign(
key: str,
coll: str,
enums: list[tuple[str, Any]],
collections: list[CollectionProperty],
*,
remove: bool = True,
) -> None:
coll_prop = next(c for c in collections if c.identifier == coll)
if remove:
collections.remove(coll_prop)
enum = next(e for e in enums if e[0] == key)
collections.insert(enums.index(enum), coll_prop)
def _generate_id_types() -> dict[str, IDType]:
prop = cast(EnumProperty, bpy.types.KeyingSetPath.bl_rna.properties['id_type'])
enums = [(k, v.icon) for k, v in prop.enum_items.items()]
collections = [
cast(CollectionProperty, p)
for p in bpy.types.BlendData.bl_rna.properties
if p.type == 'COLLECTION']
collections.sort(key=lambda c: c.identifier)
if bpy.app.version >= (4, 3, 0):
if bpy.app.version >= (5, 0, 0):
collections.remove(next(c for c in collections if c.identifier == 'annotations'))
_assign('CURVES', 'hair_curves', enums, collections)
if bpy.app.version >= (5, 0, 0):
_assign('GREASEPENCIL', 'grease_pencils', enums, collections, remove=False)
_assign('GREASEPENCIL_V3', 'grease_pencils', enums, collections)
else:
_assign('GREASEPENCIL', 'grease_pencils', enums, collections)
_assign('GREASEPENCIL_V3', 'grease_pencils_v3', enums, collections)
_assign('KEY', 'shape_keys', enums, collections)
_assign('LIGHT_PROBE', 'lightprobes', enums, collections)
else:
_assign('CURVES', 'hair_curves', enums, collections)
_assign('GREASEPENCIL_V3', 'grease_pencils', enums, collections, remove=False)
_assign('KEY', 'shape_keys', enums, collections)
_assign('LIGHT', 'lights', enums, collections)
_assign('LIGHT_PROBE', 'lightprobes', enums, collections)
id_types = {'UNDEFINED': IDType("undefined", 'QUESTION', '')}
for (key, icon), coll_prop in zip(enums, collections):
label = coll_prop.name.lower()
coll = coll_prop.identifier
props = coll_prop.fixed_type.bl_rna.properties
is_ntree = 'node_tree' in props or 'nodes' in props
id_types[key] = IDType(label, icon, coll, is_ntree)
if 'type' not in props:
continue
for subkey, subval in cast(EnumProperty, props['type']).enum_items.items():
subicon = subval.icon if subval.icon != 'NONE' else icon
id_types[f'{subkey}_{key}'] = IDType(label, subicon, coll)
for key, val in id_types.items():
val.is_object_data = f"{key.split('_')[-1]}_OBJECT" in id_types
id_types['SHADER_NODETREE'].icon = 'NODE_MATERIAL'
id_types['TEXTURE_NODETREE'].icon = 'NODE_TEXTURE'
id_types['META'].icon = 'OUTLINER_DATA_META'
return id_types
def get_id_type(id_data: bpy.types.ID) -> str:
id_type = getattr(id_data, 'type', '')
if id_type != (k := id_data.id_type):
id_type += f'_{k}' if id_type else k
return id_type if id_type in ID_TYPES else 'UNDEFINED'
ID_TYPES = _generate_id_types()