104 lines
3.4 KiB
Python
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()
|