import json import logging import os import random import string import sys from uuid import uuid4 from collections.abc import Iterable import bpy import mathutils from . import environment, presence from .libs import dump_anything logger = logging.getLogger(__name__) logger.setLevel(logging.ERROR) def has_action(target): return (hasattr(target, 'animation_data') and target.animation_data and target.animation_data.action) def has_driver(target): return (hasattr(target, 'animation_data') and target.animation_data and target.animation_data.drivers) def find_from_attr(attr_name, attr_value, list): for item in list: if getattr(item, attr_name, None) == attr_value: return item return None def get_datablock_users(datablock): users = [] supported_types = bpy.context.window_manager.session.supported_datablock if hasattr(datablock, 'users_collection') and datablock.users_collection: users.extend(list(datablock.users_collection)) if hasattr(datablock, 'users_scene') and datablock.users_scene: users.extend(list(datablock.users_scene)) if hasattr(datablock, 'users_group') and datablock.users_scene: users.extend(list(datablock.users_scene)) for datatype in supported_types: if datatype.bl_name != 'users': root = getattr(bpy.data, datatype.bl_name) for item in root: if hasattr(item, 'data') and datablock == item.data or \ datatype.bl_name != 'collections' and hasattr(item, 'children') and datablock in item.children: users.append(item) return users def random_string_digits(stringLength=6): """Generate a random string of letters and digits """ lettersAndDigits = string.ascii_letters + string.digits return ''.join(random.choice(lettersAndDigits) for i in range(stringLength)) def clean_scene(): for type_name in dir(bpy.data): try: type_collection = getattr(bpy.data, type_name) for item in type_collection: type_collection.remove(item) except: continue def revers(d): l = [] for i in d: l.append(i) return l[::-1] def get_armature_edition_context(armature): override = {} # Set correct area for area in bpy.data.window_managers[0].windows[0].screen.areas: if area.type == 'VIEW_3D': override = bpy.context.copy() override['area'] = area break # Set correct armature settings override['window'] = bpy.data.window_managers[0].windows[0] override['screen'] = bpy.data.window_managers[0].windows[0].screen override['mode'] = 'EDIT_ARMATURE' override['active_object'] = armature override['selected_objects'] = [armature] for o in bpy.data.objects: if o.data == armature: override['edit_object'] = o break return override def get_selected_objects(scene): return [obj.uuid for obj in scene.objects if obj.select_get()] def load_dict(src_dict, target): try: for item in src_dict: # attr = setattr(target, item, src_dict[item]) except Exception as e: logger.error(e) pass def dump_datablock(datablock, depth): if datablock: dumper = dump_anything.Dumper() dumper.type_subset = dumper.match_subset_all dumper.depth = depth datablock_type = datablock.bl_rna.name key = "{}/{}".format(datablock_type, datablock.name) data = dumper.dump(datablock) return data def dump_datablock_attibutes(datablock=None, attributes=[], depth=1, dickt=None): if datablock: dumper = dump_anything.Dumper() dumper.type_subset = dumper.match_subset_all dumper.depth = depth datablock_type = datablock.bl_rna.name data = {} if dickt: data = dickt for attr in attributes: try: data[attr] = dumper.dump(getattr(datablock, attr)) except: pass return data def resolve_from_id(id, optionnal_type=None): for category in dir(bpy.data): root = getattr(bpy.data, category) if isinstance(root, Iterable): if id in root and ((optionnal_type is None) or (optionnal_type.lower() in root[id].__class__.__name__.lower())): return root[id] return None