2019-05-03 22:20:40 +08:00
|
|
|
import json
|
2019-09-30 19:35:50 +08:00
|
|
|
import logging
|
2019-08-08 21:00:07 +08:00
|
|
|
import os
|
2019-08-08 21:35:43 +08:00
|
|
|
import random
|
2019-09-30 19:35:50 +08:00
|
|
|
import string
|
|
|
|
import sys
|
|
|
|
from uuid import uuid4
|
2019-11-25 23:01:48 +08:00
|
|
|
from collections.abc import Iterable
|
2019-05-02 23:58:37 +08:00
|
|
|
|
|
|
|
import bpy
|
|
|
|
import mathutils
|
|
|
|
|
2019-09-30 19:35:50 +08:00
|
|
|
from . import environment, presence
|
2019-05-02 23:58:37 +08:00
|
|
|
from .libs import dump_anything
|
2019-04-10 23:01:21 +08:00
|
|
|
|
2019-04-19 21:46:54 +08:00
|
|
|
logger = logging.getLogger(__name__)
|
2020-01-20 00:21:16 +08:00
|
|
|
logger.setLevel(logging.INFO)
|
2019-08-08 21:00:07 +08:00
|
|
|
|
2019-11-25 23:18:26 +08:00
|
|
|
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)
|
2019-09-16 23:24:48 +08:00
|
|
|
|
2019-10-07 23:32:56 +08:00
|
|
|
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
|
|
|
|
|
|
|
|
|
2019-09-27 04:57:39 +08:00
|
|
|
def get_datablock_users(datablock):
|
2019-09-16 23:24:48 +08:00
|
|
|
users = []
|
|
|
|
supported_types = bpy.context.window_manager.session.supported_datablock
|
2019-09-30 19:35:50 +08:00
|
|
|
if hasattr(datablock, 'users_collection') and datablock.users_collection:
|
2019-09-16 23:24:48 +08:00
|
|
|
users.extend(list(datablock.users_collection))
|
2019-09-30 19:35:50 +08:00
|
|
|
if hasattr(datablock, 'users_scene') and datablock.users_scene:
|
2019-09-16 23:24:48 +08:00
|
|
|
users.extend(list(datablock.users_scene))
|
2019-09-30 19:35:50 +08:00
|
|
|
if hasattr(datablock, 'users_group') and datablock.users_scene:
|
2019-09-16 23:24:48 +08:00
|
|
|
users.extend(list(datablock.users_scene))
|
|
|
|
for datatype in supported_types:
|
|
|
|
if datatype.bl_name != 'users':
|
2019-09-30 19:35:50 +08:00
|
|
|
root = getattr(bpy.data, datatype.bl_name)
|
2019-09-16 23:24:48 +08:00
|
|
|
for item in root:
|
|
|
|
if hasattr(item, 'data') and datablock == item.data or \
|
2019-09-30 19:35:50 +08:00
|
|
|
datatype.bl_name != 'collections' and hasattr(item, 'children') and datablock in item.children:
|
2019-09-16 23:24:48 +08:00
|
|
|
users.append(item)
|
|
|
|
return users
|
|
|
|
|
|
|
|
|
2019-08-08 21:35:43 +08:00
|
|
|
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))
|
|
|
|
|
2019-09-16 23:24:48 +08:00
|
|
|
|
2019-08-08 21:35:43 +08:00
|
|
|
def clean_scene():
|
2019-09-27 04:57:39 +08:00
|
|
|
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
|
2019-08-08 21:00:07 +08:00
|
|
|
|
|
|
|
|
2019-05-04 00:52:49 +08:00
|
|
|
def revers(d):
|
|
|
|
l = []
|
|
|
|
for i in d:
|
|
|
|
l.append(i)
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-05-04 00:52:49 +08:00
|
|
|
return l[::-1]
|
2019-05-02 23:58:37 +08:00
|
|
|
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-05-03 20:55:18 +08:00
|
|
|
def get_armature_edition_context(armature):
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-05-03 22:20:40 +08:00
|
|
|
override = {}
|
2019-05-03 20:55:18 +08:00
|
|
|
# Set correct area
|
2019-05-08 23:06:52 +08:00
|
|
|
for area in bpy.data.window_managers[0].windows[0].screen.areas:
|
2019-05-03 20:55:18 +08:00
|
|
|
if area.type == 'VIEW_3D':
|
2019-05-03 22:20:40 +08:00
|
|
|
override = bpy.context.copy()
|
2019-05-03 20:55:18 +08:00
|
|
|
override['area'] = area
|
|
|
|
break
|
|
|
|
|
|
|
|
# Set correct armature settings
|
2019-05-08 23:06:52 +08:00
|
|
|
override['window'] = bpy.data.window_managers[0].windows[0]
|
2019-05-03 22:20:40 +08:00
|
|
|
override['screen'] = bpy.data.window_managers[0].windows[0].screen
|
2019-05-03 20:55:18 +08:00
|
|
|
override['mode'] = 'EDIT_ARMATURE'
|
|
|
|
override['active_object'] = armature
|
|
|
|
override['selected_objects'] = [armature]
|
|
|
|
|
|
|
|
for o in bpy.data.objects:
|
|
|
|
if o.data == armature:
|
2019-05-03 22:20:40 +08:00
|
|
|
override['edit_object'] = o
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-05-03 20:55:18 +08:00
|
|
|
break
|
|
|
|
|
|
|
|
return override
|
2019-04-18 21:05:48 +08:00
|
|
|
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-04-17 22:15:21 +08:00
|
|
|
def get_selected_objects(scene):
|
2019-10-09 03:48:45 +08:00
|
|
|
return [obj.uuid for obj in scene.objects if obj.select_get()]
|
2019-04-18 21:05:48 +08:00
|
|
|
|
2019-09-16 23:24:48 +08:00
|
|
|
|
2019-08-08 21:00:07 +08:00
|
|
|
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
|
|
|
|
|
2019-09-16 23:24:48 +08:00
|
|
|
|
2019-04-11 00:01:55 +08:00
|
|
|
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
|
|
|
|
|
2019-05-14 17:00:38 +08:00
|
|
|
|
2019-08-08 21:00:07 +08:00
|
|
|
def dump_datablock_attibutes(datablock=None, attributes=[], depth=1, dickt=None):
|
2019-04-11 00:01:55 +08:00
|
|
|
if datablock:
|
|
|
|
dumper = dump_anything.Dumper()
|
|
|
|
dumper.type_subset = dumper.match_subset_all
|
|
|
|
dumper.depth = depth
|
|
|
|
|
2019-05-13 17:49:46 +08:00
|
|
|
datablock_type = datablock.bl_rna.name
|
2019-04-11 00:01:55 +08:00
|
|
|
|
|
|
|
data = {}
|
2019-05-08 23:06:52 +08:00
|
|
|
|
2019-05-04 00:52:49 +08:00
|
|
|
if dickt:
|
|
|
|
data = dickt
|
2019-04-11 00:01:55 +08:00
|
|
|
for attr in attributes:
|
|
|
|
try:
|
|
|
|
data[attr] = dumper.dump(getattr(datablock, attr))
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2019-09-30 19:35:50 +08:00
|
|
|
return data
|
2019-11-25 23:01:48 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
|