multi-user/multi_user/utils.py

168 lines
5.1 KiB
Python
Raw Normal View History

2020-03-20 21:56:50 +08:00
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####
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-09-30 19:35:50 +08:00
import sys
2020-03-24 00:55:10 +08:00
import time
from collections.abc import Iterable
2020-09-21 22:47:49 +08:00
from pathlib import Path
from uuid import uuid4
import math
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-04-10 23:01:21 +08:00
2020-01-22 21:33:34 +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):
users = []
supported_types = get_preferences().supported_datablocks
2019-09-30 19:35:50 +08:00
if hasattr(datablock, 'users_collection') and datablock.users_collection:
users.extend(list(datablock.users_collection))
2019-09-30 19:35:50 +08:00
if hasattr(datablock, 'users_scene') and datablock.users_scene:
users.extend(list(datablock.users_scene))
2019-09-30 19:35:50 +08:00
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':
2019-09-30 19:35:50 +08:00
root = getattr(bpy.data, datatype.bl_name)
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:
users.append(item)
return users
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:
2020-09-19 05:09:47 +08:00
type_collection.remove(item)
2019-09-27 04:57:39 +08:00
except:
continue
2019-08-08 21:00:07 +08:00
def get_selected_objects(scene, active_view_layer):
return [obj.uuid for obj in scene.objects if obj.select_get(view_layer=active_view_layer)]
2019-04-18 21:05: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
2020-09-21 22:47:49 +08:00
def get_datablock_from_uuid(uuid, default, ignore=[]):
if not uuid:
return default
2020-09-18 05:45:09 +08:00
for category in dir(bpy.data):
root = getattr(bpy.data, category)
if isinstance(root, Iterable) and category not in ignore:
2020-09-18 05:45:09 +08:00
for item in root:
if getattr(item, 'uuid', None) == uuid:
2020-09-21 22:47:49 +08:00
return item
2020-09-18 05:45:09 +08:00
return default
2020-09-21 22:47:49 +08:00
def get_preferences():
2020-03-24 00:55:10 +08:00
return bpy.context.preferences.addons[__package__].preferences
2020-03-24 00:55:10 +08:00
def current_milli_time():
return int(round(time.time() * 1000))
def get_expanded_icon(prop: bpy.types.BoolProperty) -> str:
if prop:
return 'DISCLOSURE_TRI_DOWN'
else:
return 'DISCLOSURE_TRI_RIGHT'
2020-09-21 22:47:49 +08:00
# Taken from here: https://stackoverflow.com/a/55659577
def get_folder_size(folder):
return ByteSize(sum(file.stat().st_size for file in Path(folder).rglob('*')))
class ByteSize(int):
_kB = 1024
_suffixes = 'B', 'kB', 'MB', 'GB', 'PB'
def __new__(cls, *args, **kwargs):
return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
self.bytes = self.B = int(self)
self.kilobytes = self.kB = self / self._kB**1
self.megabytes = self.MB = self / self._kB**2
self.gigabytes = self.GB = self / self._kB**3
self.petabytes = self.PB = self / self._kB**4
*suffixes, last = self._suffixes
suffix = next((
suffix
for suffix in suffixes
if 1 < getattr(self, suffix) < self._kB
), last)
self.readable = suffix, getattr(self, suffix)
super().__init__()
def __str__(self):
return self.__format__('.2f')
def __repr__(self):
return '{}({})'.format(self.__class__.__name__, super().__repr__())
def __format__(self, format_spec):
suffix, val = self.readable
return '{val:{fmt}} {suf}'.format(val=math.ceil(val), fmt=format_spec, suf=suffix)
def __sub__(self, other):
return self.__class__(super().__sub__(other))
def __add__(self, other):
return self.__class__(super().__add__(other))
def __mul__(self, other):
return self.__class__(super().__mul__(other))
def __rsub__(self, other):
return self.__class__(super().__sub__(other))
def __radd__(self, other):
return self.__class__(super().__add__(other))
def __rmul__(self, other):
return self.__class__(super().__rmul__(other))