-
Notifications
You must be signed in to change notification settings - Fork 11
/
HaydeeUtils.py
191 lines (155 loc) · 6.76 KB
/
HaydeeUtils.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# <pep8 compliant>
import bpy
from bpy.props import EnumProperty
NAME_LIMIT = 31
file_format_prop = EnumProperty(
name="File Format",
description="Select file format Haydee 1 / Haydee 2 (flipped UV)",
items=(('H1', 'Haydee 1', 'Use Haydee 1 File Format'),
('H2', 'Haydee 2', 'Use Haydee 2 File Format'),
),
default='H2',
)
def boneRenameBlender(bone_name):
name = bone_name
if name.startswith("SK_R_"):
name = "SK_" + name[5:] + "_R"
if name.startswith("SK_L_"):
name = "SK_" + name[5:] + "_L"
return stripName(name)
def boneRenameHaydee(bone_name):
name = bone_name
if name.startswith("SK_") and name.endswith("_R"):
name = "SK_R_" + name[3:-2]
if name.startswith("SK_") and name.endswith("_L"):
name = "SK_L_" + name[3:-2]
return stripName(name)[:NAME_LIMIT]
def stripName(name):
return name.replace(" ", "_").replace("*", "_").replace("-", "_")
def decodeText(text):
return text.decode('latin1').split('\0', 1)[0]
def d(number):
r = ('%.6f' % number).rstrip('0').rstrip('.')
if r == "-0":
return "0"
return r
# --------------------------------------------------------------------------------
# Finds a suitable armature in the current selection or scene
# --------------------------------------------------------------------------------
def find_armature(operator, context):
armature = None
checking = "ARMATURE"
obj_list = [context.active_object, ] if context.active_object.type == checking else None
if not obj_list:
obj_list = context.selected_objects
if not obj_list:
obj_list = context.scene.objects
while True:
for ob in obj_list:
if ob.type == checking:
if checking == "MESH":
armature = ob.find_armature()
if armature:
ob = armature
break
if ob.type != 'ARMATURE':
continue
if armature is not None and armature != ob:
operator.report({'ERROR'}, "Multiples armatures found, please select a single one and try again")
armature = ob
if armature is not None:
return armature
if checking == "ARMATURE":
checking = "MESH"
else:
operator.report({'ERROR'}, "No armature found in scene" if obj_list == context.scene.objects else "No armature or weighted mesh selected")
return None
def materials_list(a, b):
materials = {}
for ob in bpy.context.scene.objects:
if ob.type == "MESH":
for material_slot in ob.material_slots:
materials[material_slot.name] = True
mat_list = [('__ALL__', 'Export all materials', '')]
for name in materials.keys():
mat_list.append((name, name, ''))
return mat_list
def fit_to_armature():
"""Fit selected armatures to the active armature.
Replaces selected armature with active armature.
Also modifies the pose of the meshes.
"""
active = bpy.context.active_object
if not (active and active.type == 'ARMATURE'):
return {'FINISHED'}
selected = next((armature for armature in bpy.context.selected_objects if (armature.type == 'ARMATURE' and armature != active)), None)
if not (selected and selected.type == 'ARMATURE'):
return {'FINISHED'}
match_to_armature(selected, active)
apply_pose(selected, active)
bpy.data.armatures.remove(selected.data, do_unlink=True)
return {'FINISHED'}
def match_to_armature(armature, target):
for pose_bone in armature.pose.bones:
if target.pose.bones.get(pose_bone.name):
constraint = pose_bone.constraints.new('COPY_TRANSFORMS')
constraint.target = target
constraint.subtarget = pose_bone.name
def apply_pose(selected, active):
objs = [obj for obj in bpy.data.objects if (obj.parent == selected)]
modifiers = [modif for obj in bpy.data.objects for modif in obj.modifiers if (modif.type == 'ARMATURE' and modif.object == selected)]
for obj in objs:
obj.parent = active
for modif in modifiers:
obj = modif.id_data
bpy.context.view_layer.objects.active = obj
index = obj.modifiers.find(modif.name)
bpy.ops.object.modifier_copy(modifier=modif.name)
new_modif_name = obj.modifiers[index + 1].name
bpy.ops.object.modifier_apply(apply_as='DATA', modifier=new_modif_name)
modif.object = active
bpy.context.view_layer.objects.active = active
def fit_to_mesh():
"""Fit selected armatures to active."""
active = bpy.context.active_object
if not (active and active.type == 'ARMATURE'):
return {'FINISHED'}
selected = next((armature for armature in bpy.context.selected_objects if (armature.type == 'ARMATURE' and armature != active)), None)
if not (selected and selected.type == 'ARMATURE'):
return {'FINISHED'}
match_to_armature(active, selected)
new_rest_pose(selected, active)
bpy.data.armatures.remove(selected.data, do_unlink=True)
return {'FINISHED'}
def new_rest_pose(selected, active):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
bpy.context.view_layer.objects.active = active
bpy.ops.object.mode_set(mode='POSE', toggle=False)
bpy.ops.pose.armature_apply()
for pose_bone in active.pose.bones:
for constraint in pose_bone.constraints:
if constraint.type == 'COPY_TRANSFORMS':
pose_bone.constraints.remove(constraint)
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
objs = [obj for obj in bpy.data.objects if (obj.parent == selected)]
modifiers = [modif for obj in bpy.data.objects for modif in obj.modifiers if (modif.type == 'ARMATURE' and modif.object == selected)]
for obj in objs:
obj.parent = active
for modif in modifiers:
modif.object = active
class HaydeeToolFitArmature_Op(bpy.types.Operator):
bl_idname = 'haydee_tools.fit_to_armature'
bl_label = 'Cycles'
bl_description = 'Select the mesh armature then the haydee Skel. Raplces the Armature with the skel. Uses the Skel pose'
bl_options = {'PRESET'}
def execute(self, context):
fit_to_armature()
return {'FINISHED'}
class HaydeeToolFitMesh_Op(bpy.types.Operator):
bl_idname = 'haydee_tools.fit_to_mesh'
bl_label = 'Cycles'
bl_description = 'Select the mesh armature then the haydee Skel. Raplces the Armature with the skel. Uses the Armature pose'
bl_options = {'PRESET'}
def execute(self, context):
fit_to_mesh()
return {'FINISHED'}