-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathmainFunctions.py
236 lines (187 loc) · 7.86 KB
/
mainFunctions.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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import bpy
import numpy
from .jsonFunctions import objectDataToDico
from .. import __package__
def get_collection(context):
bw_collection_name = context.preferences.addons[__package__].preferences.bonewidget_collection_name
collection = context.scene.collection.children.get(bw_collection_name)
if collection:
return collection
collection = bpy.data.collections.get(bw_collection_name)
if not collection:
collection = bpy.data.collections.new(bw_collection_name)
context.scene.collection.children.link(collection)
return collection
def boneMatrix(widget, matchBone):
widget.matrix_local = matchBone.bone.matrix_local
# need to make this take the armature scale into account
# id_data below now points to the armature data rather than the object
# widget.matrix_world = bpy.context.active_pose_bone.id_data.matrix_world @ matchBone.bone.matrix_local
# widget.matrix_world = matchBone.matrix_world @ matchBone.bone.matrix_local
widget.scale = [matchBone.bone.length, matchBone.bone.length, matchBone.bone.length]
widget.data.update()
def fromWidgetFindBone(widget):
matchBone = None
for ob in bpy.context.scene.objects:
if ob.type == "ARMATURE":
for bone in ob.pose.bones:
if bone.custom_shape == widget:
matchBone = bone
return matchBone
def createWidget(bone, widget, relative, size, scale, slide, collection):
C = bpy.context
D = bpy.data
bw_widget_prefix = C.preferences.addons[__package__].preferences.widget_prefix
if bone.custom_shape_transform:
matrixBone = bone.custom_shape_transform
else:
matrixBone = bone
if bone.custom_shape:
bone.custom_shape.name = bone.custom_shape.name+"_old"
bone.custom_shape.data.name = bone.custom_shape.data.name+"_old"
if C.scene.collection.objects.get(bone.custom_shape.name):
C.scene.collection.objects.unlink(bone.custom_shape)
# make the data name include the prefix
newData = D.meshes.new(bw_widget_prefix + bone.name)
if relative == True:
boneLength = 1
else:
boneLength = (1/bone.bone.length)
newData.from_pydata(numpy.array(widget['vertices'])*[size*scale[0]*boneLength, size*scale[2]
* boneLength, size*scale[1]*boneLength]+[0, slide, 0], widget['edges'], widget['faces'])
newData.update(calc_edges=True)
newObject = D.objects.new(bw_widget_prefix + bone.name, newData)
newObject.data = newData
newObject.name = bw_widget_prefix + bone.name
# C.scene.collection.objects.link(newObject)
collection.objects.link(newObject)
# When it creates the widget it still doesn't take the armature scale into account
newObject.matrix_world = matrixBone.bone.matrix_local
newObject.scale = [matrixBone.bone.length, matrixBone.bone.length, matrixBone.bone.length]
layer = bpy.context.view_layer
layer.update()
bone.custom_shape = newObject
bone.bone.show_wire = True
def symmetrizeWidget(bone, collection):
C = bpy.context
D = bpy.data
bw_widget_prefix = C.preferences.addons[__package__].preferences.widget_prefix
widget = bone.custom_shape
if findMirrorObject(bone).custom_shape_transform:
mirrorBone = findMirrorObject(bone).custom_shape_transform
else:
mirrorBone = findMirrorObject(bone)
mirrorWidget = mirrorBone.custom_shape
if mirrorWidget:
mirrorWidget.name = mirrorWidget.name+"_old"
mirrorWidget.data.name = mirrorWidget.data.name+"_old"
# don't unlink
'''
if C.scene.objects.get(mirrorWidget.name):
C.scene.objects.unlink(mirrorWidget)
'''
newData = widget.data.copy()
for vert in newData.vertices:
vert.co = numpy.array(vert.co)*(-1, 1, 1)
newObject = widget.copy()
newObject.data = newData
newData.update()
newObject.name = bw_widget_prefix + mirrorBone.name
collection.objects.link(newObject)
# C.scene.objects.link(newObject)
newObject.matrix_local = mirrorBone.bone.matrix_local
newObject.scale = [mirrorBone.bone.length, mirrorBone.bone.length, mirrorBone.bone.length]
layer = bpy.context.view_layer
layer.update()
mirrorBone.custom_shape = newObject
mirrorBone.bone.show_wire = True
def editWidget(active_bone):
C = bpy.context
D = bpy.data
widget = active_bone.custom_shape
armature = active_bone.id_data
bpy.ops.object.mode_set(mode='OBJECT')
C.active_object.select_set(False)
'''
if C.space_data.lock_camera_and_layers == False :
visibleLayers = numpy.array(bpy.context.space_data.layers)+widget.layers-armature.layers
bpy.context.space_data.layers = visibleLayers.tolist()
else :
visibleLayers = numpy.array(bpy.context.scene.layers)+widget.layers-armature.layers
bpy.context.scene.layers = visibleLayers.tolist()
'''
collection = get_collection(C)
collection.hide_viewport = False
if C.space_data.local_view:
bpy.ops.view3d.localview()
# select object and make it active
widget.select_set(True)
bpy.context.view_layer.objects.active = widget
bpy.ops.object.mode_set(mode='EDIT')
def returnToArmature(widget):
C = bpy.context
D = bpy.data
bone = fromWidgetFindBone(widget)
armature = bone.id_data
if C.active_object.mode == 'EDIT':
bpy.ops.object.mode_set(mode='OBJECT')
'''
if C.space_data.lock_camera_and_layers == False :
visibleLayers = numpy.array(bpy.context.space_data.layers)-widget.layers+armature.layers
bpy.context.space_data.layers = visibleLayers.tolist()
else :
visibleLayers = numpy.array(bpy.context.scene.layers)-widget.layers+armature.layers
bpy.context.scene.layers = visibleLayers.tolist()
'''
collection = get_collection(C)
collection.hide_viewport = True
if C.space_data.local_view:
bpy.ops.view3d.localview()
bpy.context.view_layer.objects.active = armature
armature.select_set(True)
bpy.ops.object.mode_set(mode='POSE')
armature.data.bones[bone.name].select = True
armature.data.bones.active = armature.data.bones[bone.name]
def findMirrorObject(object):
if object.name.endswith("L"):
suffix = 'R'
elif object.name.endswith("R"):
suffix = 'L'
elif object.name.endswith("l"):
suffix = 'r'
elif object.name.endswith("r"):
suffix = 'l'
else: # what if the widget ends in .001?
print('Object suffix unknown using blank')
suffix = ''
objectName = list(object.name)
objectBaseName = objectName[:-1]
mirroredObjectName = "".join(objectBaseName)+suffix
if object.id_data.type == 'ARMATURE':
return object.id_data.pose.bones.get(mirroredObjectName)
else:
return bpy.context.scene.objects.get(mirroredObjectName)
def findMatchBones():
C = bpy.context
D = bpy.data
widgetsAndBones = {}
if bpy.context.object.type == 'ARMATURE':
for bone in C.selected_pose_bones:
if bone.name.endswith("L") or bone.name.endswith("R"):
widgetsAndBones[bone] = bone.custom_shape
mirrorBone = findMirrorObject(bone)
if mirrorBone:
widgetsAndBones[mirrorBone] = mirrorBone.custom_shape
armature = bpy.context.object
activeObject = C.active_pose_bone
else:
for shape in C.selected_objects:
bone = fromWidgetFindBone(shape)
if bone.name.endswith("L") or bone.name.endswith("R"):
widgetsAndBones[fromWidgetFindBone(shape)] = shape
mirrorShape = findMirrorObject(shape)
if mirrorShape:
widgetsAndBones[mirrorShape] = mirrorShape
activeObject = fromWidgetFindBone(C.object)
armature = activeObject.id_data
return (widgetsAndBones, activeObject, armature)