-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.py
99 lines (78 loc) · 3.07 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import hashlib
import math
import bpy
import mathutils
def console_get():
for area in bpy.context.screen.areas:
if area.type == 'CONSOLE':
for space in area.spaces:
if space.type == 'CONSOLE':
for region in area.regions:
if region.type == 'WINDOW':
return area, space, region
return None, None, None
def console_write(text):
area, space, region = console_get()
if area is None:
return
context_override = bpy.context.copy()
context_override.update({
"space": space,
"area": area,
"region": region,
})
with bpy.context.temp_override(**context_override):
for line in text.split("\n"):
bpy.ops.console.scrollback_append(text=line, type='OUTPUT')
print = lambda x: console_write(str(x))
def print_rot_loc_matrix(intro: str, data):
import mathutils
loc = mathutils.Vector([0,0,0])
if isinstance(data, mathutils.Quaternion):
rot = data
else:
loc, rot, _ = data.decompose()
rot = rot.to_euler()
print(f'{intro}:\tRX={math.degrees(rot.x):> z6.1f}\tRY={math.degrees(rot.y):> z6.1f}\tRZ={math.degrees(rot.z):> z6.1f}\tX={loc.x: 1.3f}\tY={loc.y: 1.3f}\tZ={loc.z: 1.3f}')
def flip_image_y(image):
import itertools
width, height = image.size
row_size = width * image.channels
pixels_orig = image.pixels[:]
pixels = (pixels_orig[(height - row - 1) * row_size: (height - row) * row_size] for row in range(height))
pixels = itertools.chain.from_iterable(pixels)
pixels = list(pixels)
image.pixels[:] = pixels
return image
def get_hash(s: str) -> str:
return hashlib.md5(bytes(s, 'utf8')).hexdigest()
def add_driver(obj, obj_prop_path: str, target_id: str, target_data_path: str, fallback_value, index: int = -1):
if index != -1:
drivers = [obj.driver_add(obj_prop_path, index).driver]
else:
drivers = [d.driver for d in obj.driver_add(obj_prop_path, index)]
for driver in drivers:
var = driver.variables.new()
driver.type = 'SUM'
var.targets[0].id = target_id
# TODO set var.targets[0] type to armature
var.targets[0].data_path = target_data_path
var.targets[0].use_fallback_value = True
var.targets[0].fallback_value = fallback_value
return drivers
def get_weighted_vertex_groups(obj):
used_groups = {g.group for v in obj.data.vertices for g in v.groups if g.weight > 0.001}
return [v for v in obj.vertex_groups if v.index in used_groups]
def get_single_bone_name(obj, vertex_groups, vertex_group_whitelist) -> str:
if obj.parent_type == 'BONE' and obj.parent_bone != '':
return obj.parent_bone
vertex_groups = [v for v in vertex_groups if v.name in vertex_group_whitelist]
if len(vertex_groups) > 1:
return None
for v in obj.data.vertices:
if len(v.groups) == 0:
return None
max_veight = max(g.weight for g in v.groups)
if max_veight < 0.997:
return None
return vertex_groups[0].name