Newer
Older
#====================== 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#======================= END GPL LICENSE BLOCK ========================
import importlib
Nathan Vegdahl
committed
import math
import random
import time
Lucio Rossi
committed
import os
from mathutils import Vector, Matrix, Color
from rna_prop_ui import rna_idprop_ui_prop_get
RIG_DIR = "rigs" # Name of the directory where rig types are kept
METARIG_DIR = "metarigs" # Name of the directory where metarigs are kept
ORG_PREFIX = "ORG-" # Prefix of original bones.
MCH_PREFIX = "MCH-" # Prefix of mechanism bones.
DEF_PREFIX = "DEF-" # Prefix of deformation bones.
WGT_PREFIX = "WGT-" # Prefix for widget objects
ROOT_NAME = "root" # Name of the root bone.
WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
MODULE_NAME = "rigify" # Windows/Mac blender is weird, so __package__ doesn't work
outdated_types = {"pitchipoy.limbs.super_limb": "limbs.super_limb",
"pitchipoy.limbs.super_arm": "limbs.super_limb",
"pitchipoy.limbs.super_leg": "limbs.super_limb",
"pitchipoy.limbs.super_front_paw": "limbs.super_limb",
"pitchipoy.limbs.super_rear_paw": "limbs.super_limb",
"pitchipoy.super_torso_turbo": "spines.super_spine",
"pitchipoy.simple_tentacle": "limbs.simple_tentacle",
"pitchipoy.super_face": "faces.super_face",
"pitchipoy.super_palm": "limbs.super_palm",
"pitchipoy.super_copy": "basic.super_copy",
"palm": "limbs.super_palm",
"basic.copy": "basic.super_copy"}
#=======================================================================
# Error handling
#=======================================================================
class MetarigError(Exception):
""" Exception raised for errors.
"""
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
#=======================================================================
# Name manipulation
#=======================================================================
def strip_trailing_number(s):
m = re.search(r'\.(\d{3})$', s)
return s[0:-4] if m else s
def unique_name(collection, base_name):
base_name = strip_trailing_number(base_name)
count = 1
name = base_name
while collection.get(name):
name = "%s.%03d" % (base_name, count)
count += 1
return name
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
def org_name(name):
""" Returns the name with ORG_PREFIX stripped from it.
"""
if name.startswith(ORG_PREFIX):
return name[len(ORG_PREFIX):]
else:
return name
def strip_org(name):
""" Returns the name with ORG_PREFIX stripped from it.
"""
if name.startswith(ORG_PREFIX):
return name[len(ORG_PREFIX):]
else:
return name
org_name = strip_org
def org(name):
""" Prepends the ORG_PREFIX to a name if it doesn't already have
it, and returns it.
"""
if name.startswith(ORG_PREFIX):
return name
else:
return ORG_PREFIX + name
make_original_name = org
def mch(name):
""" Prepends the MCH_PREFIX to a name if it doesn't already have
it, and returns it.
"""
if name.startswith(MCH_PREFIX):
return name
else:
return MCH_PREFIX + name
make_mechanism_name = mch
def deformer(name):
""" Prepends the DEF_PREFIX to a name if it doesn't already have
it, and returns it.
"""
if name.startswith(DEF_PREFIX):
return name
else:
return DEF_PREFIX + name
make_deformer_name = deformer
def insert_before_lr(name, text):
if name[-1] in ['l', 'L', 'r', 'R'] and name[-2] in ['.', '-', '_']:
return name[:-2] + text + name[-2:]
else:
return name + text
def upgradeMetarigTypes(metarig, revert=False):
"""Replaces rigify_type properties from old versions with their current names
:param revert: revert types to previous version (if old type available)
"""
if revert:
vals = list(outdated_types.values())
rig_defs = {v: k for k, v in outdated_types.items() if vals.count(v) == 1}
else:
rig_defs = outdated_types
for bone in metarig.pose.bones:
rg_type = bone.rigify_type
if rg_type in rig_defs:
bone.rigify_type = rig_defs[rg_type]
#=======================
# Bone manipulation
#=======================
def new_bone(obj, bone_name):
""" Adds a new bone to the given armature object.
Returns the resulting bone's name.
"""
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
edit_bone = obj.data.edit_bones.new(bone_name)
name = edit_bone.name
edit_bone.head = (0, 0, 0)
edit_bone.tail = (0, 1, 0)
edit_bone.roll = 0
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='EDIT')
return name
else:
raise MetarigError("Can't add new bone '%s' outside of edit mode" % bone_name)
def copy_bone_simple(obj, bone_name, assign_name=''):
""" Makes a copy of the given bone in the given armature object.
but only copies head, tail positions and roll. Does not
address parenting either.
"""
#if bone_name not in obj.data.bones:
if bone_name not in obj.data.edit_bones:
raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name)
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
if assign_name == '':
assign_name = bone_name
# Copy the edit bone
edit_bone_1 = obj.data.edit_bones[bone_name]
edit_bone_2 = obj.data.edit_bones.new(assign_name)
bone_name_1 = bone_name
# Copy edit bone attributes
edit_bone_2.layers = list(edit_bone_1.layers)
edit_bone_2.head = Vector(edit_bone_1.head)
edit_bone_2.tail = Vector(edit_bone_1.tail)
edit_bone_2.roll = edit_bone_1.roll
return bone_name_2
else:
raise MetarigError("Cannot copy bones outside of edit mode")
def copy_bone(obj, bone_name, assign_name=''):
""" Makes a copy of the given bone in the given armature object.
Returns the resulting bone's name.
"""
#if bone_name not in obj.data.bones:
if bone_name not in obj.data.edit_bones:
raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name)
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
if assign_name == '':
assign_name = bone_name
# Copy the edit bone
edit_bone_1 = obj.data.edit_bones[bone_name]
edit_bone_2 = obj.data.edit_bones.new(assign_name)
bone_name_1 = bone_name
bone_name_2 = edit_bone_2.name
edit_bone_2.parent = edit_bone_1.parent
edit_bone_2.use_connect = edit_bone_1.use_connect
# Copy edit bone attributes
edit_bone_2.layers = list(edit_bone_1.layers)
edit_bone_2.head = Vector(edit_bone_1.head)
edit_bone_2.tail = Vector(edit_bone_1.tail)
edit_bone_2.roll = edit_bone_1.roll
edit_bone_2.use_inherit_rotation = edit_bone_1.use_inherit_rotation
edit_bone_2.use_inherit_scale = edit_bone_1.use_inherit_scale
edit_bone_2.use_local_location = edit_bone_1.use_local_location
edit_bone_2.use_deform = edit_bone_1.use_deform
edit_bone_2.bbone_segments = edit_bone_1.bbone_segments
edit_bone_2.bbone_in = edit_bone_1.bbone_in
edit_bone_2.bbone_out = edit_bone_1.bbone_out
bpy.ops.object.mode_set(mode='OBJECT')
# Get the pose bones
pose_bone_1 = obj.pose.bones[bone_name_1]
pose_bone_2 = obj.pose.bones[bone_name_2]
# Copy pose bone attributes
pose_bone_2.rotation_mode = pose_bone_1.rotation_mode
pose_bone_2.rotation_axis_angle = tuple(pose_bone_1.rotation_axis_angle)
pose_bone_2.rotation_euler = tuple(pose_bone_1.rotation_euler)
pose_bone_2.rotation_quaternion = tuple(pose_bone_1.rotation_quaternion)
pose_bone_2.lock_location = tuple(pose_bone_1.lock_location)
pose_bone_2.lock_scale = tuple(pose_bone_1.lock_scale)
pose_bone_2.lock_rotation = tuple(pose_bone_1.lock_rotation)
pose_bone_2.lock_rotation_w = pose_bone_1.lock_rotation_w
pose_bone_2.lock_rotations_4d = pose_bone_1.lock_rotations_4d
# Copy custom properties
for key in pose_bone_1.keys():
if key != "_RNA_UI" \
and key != "rigify_parameters" \
and key != "rigify_type":
prop1 = rna_idprop_ui_prop_get(pose_bone_1, key, create=False)
prop2 = rna_idprop_ui_prop_get(pose_bone_2, key, create=True)
pose_bone_2[key] = pose_bone_1[key]
for key in prop1.keys():
prop2[key] = prop1[key]
bpy.ops.object.mode_set(mode='EDIT')
return bone_name_2
else:
raise MetarigError("Cannot copy bones outside of edit mode")
def flip_bone(obj, bone_name):
""" Flips an edit bone.
"""
if bone_name not in obj.data.bones:
raise MetarigError("flip_bone(): bone '%s' not found, cannot copy it" % bone_name)
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
bone = obj.data.edit_bones[bone_name]
head = Vector(bone.head)
tail = Vector(bone.tail)
bone.tail = head + tail
bone.head = tail
bone.tail = head
else:
raise MetarigError("Cannot flip bones outside of edit mode")
def put_bone(obj, bone_name, pos):
""" Places a bone at the given position.
"""
if bone_name not in obj.data.bones:
Nathan Vegdahl
committed
raise MetarigError("put_bone(): bone '%s' not found, cannot move it" % bone_name)
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
bone = obj.data.edit_bones[bone_name]
delta = pos - bone.head
bone.translate(delta)
else:
raise MetarigError("Cannot 'put' bones outside of edit mode")
Nathan Vegdahl
committed
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
def make_nonscaling_child(obj, bone_name, location, child_name_postfix=""):
""" Takes the named bone and creates a non-scaling child of it at
the given location. The returned bone (returned by name) is not
a true child, but behaves like one sans inheriting scaling.
It is intended as an intermediate construction to prevent rig types
from scaling with their parents. The named bone is assumed to be
an ORG bone.
"""
if bone_name not in obj.data.bones:
raise MetarigError("make_nonscaling_child(): bone '%s' not found, cannot copy it" % bone_name)
if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE':
# Create desired names for bones
name1 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_ch")))
name2 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_intr")))
# Create bones
child = copy_bone(obj, bone_name, name1)
intermediate_parent = copy_bone(obj, bone_name, name2)
# Get edit bones
eb = obj.data.edit_bones
child_e = eb[child]
intrpar_e = eb[intermediate_parent]
# Parenting
child_e.use_connect = False
child_e.parent = None
intrpar_e.use_connect = False
intrpar_e.parent = eb[bone_name]
# Positioning
child_e.length *= 0.5
intrpar_e.length *= 0.25
put_bone(obj, child, location)
put_bone(obj, intermediate_parent, location)
# Object mode
bpy.ops.object.mode_set(mode='OBJECT')
pb = obj.pose.bones
# Add constraints
con = pb[child].constraints.new('COPY_LOCATION')
con.name = "parent_loc"
con.target = obj
con.subtarget = intermediate_parent
con = pb[child].constraints.new('COPY_ROTATION')
con.name = "parent_loc"
con.target = obj
con.subtarget = intermediate_parent
bpy.ops.object.mode_set(mode='EDIT')
return child
else:
raise MetarigError("Cannot make nonscaling child outside of edit mode")
#=============================================
# Widget creation
#=============================================
def obj_to_bone(obj, rig, bone_name):
""" Places an object at the location/rotation/scale of the given bone.
"""
if bpy.context.mode == 'EDIT_ARMATURE':
raise MetarigError("obj_to_bone(): does not work while in edit mode")
bone = rig.data.bones[bone_name]
mat = rig.matrix_world * bone.matrix_local
obj.rotation_mode = 'XYZ'
obj.rotation_euler = mat.to_euler()
scl_avg = (scl[0] + scl[1] + scl[2]) / 3
obj.scale = (bone.length * scl_avg), (bone.length * scl_avg), (bone.length * scl_avg)
def create_widget(rig, bone_name, bone_transform_name=None):
""" Creates an empty widget object for a bone, and returns the object.
"""
if bone_transform_name is None:
Lucio Rossi
committed
obj_name = WGT_PREFIX + rig.name + '_' + bone_name
Lucio Rossi
committed
id_store = bpy.context.window_manager
# Move object to bone position, in case it changed
obj = scene.objects[obj_name]
obj_to_bone(obj, rig, bone_transform_name)
# Delete object if it exists in blend data but not scene data.
# This is necessary so we can then create the object without
# name conflicts.
if obj_name in bpy.data.objects:
Nathan Vegdahl
committed
bpy.data.objects[obj_name].user_clear()
bpy.data.objects.remove(bpy.data.objects[obj_name])
mesh = bpy.data.meshes.new(obj_name)
obj = bpy.data.objects.new(obj_name, mesh)
scene.objects.link(obj)
# Move object to bone position and set layers
obj_to_bone(obj, rig, bone_transform_name)
Lucio Rossi
committed
wgts_group_name = 'WGTS_' + rig.name
if wgts_group_name in bpy.data.objects.keys():
obj.parent = bpy.data.objects[wgts_group_name]
obj.layers = WGT_LAYERS
return obj
# Common Widgets
def create_line_widget(rig, bone_name, bone_transform_name=None):
""" Creates a basic line widget, a line that spans the length of the bone.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
mesh = obj.data
mesh.from_pydata([(0, 0, 0), (0, 1, 0)], [(0, 1)], [])
mesh.update()
def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0, with_line=False, bone_transform_name=None):
""" Creates a basic circle widget, a circle around the y-axis.
radius: the radius of the circle
head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail)
"""
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
v = [(0.7071068286895752, 2.980232238769531e-07, -0.7071065306663513), (0.8314696550369263, 2.980232238769531e-07, -0.5555699467658997), (0.9238795042037964, 2.682209014892578e-07, -0.3826831877231598), (0.9807852506637573, 2.5331974029541016e-07, -0.19509011507034302), (1.0, 2.365559055306221e-07, 1.6105803979371558e-07), (0.9807853698730469, 2.2351741790771484e-07, 0.19509044289588928), (0.9238796234130859, 2.086162567138672e-07, 0.38268351554870605), (0.8314696550369263, 1.7881393432617188e-07, 0.5555704236030579), (0.7071068286895752, 1.7881393432617188e-07, 0.7071070075035095), (0.5555702447891235, 1.7881393432617188e-07, 0.8314698934555054), (0.38268327713012695, 1.7881393432617188e-07, 0.923879861831665), (0.19509008526802063, 1.7881393432617188e-07, 0.9807855486869812), (-3.2584136988589307e-07, 1.1920928955078125e-07, 1.000000238418579), (-0.19509072601795197, 1.7881393432617188e-07, 0.9807854294776917), (-0.3826838731765747, 1.7881393432617188e-07, 0.9238795638084412), (-0.5555707216262817, 1.7881393432617188e-07, 0.8314695358276367), (-0.7071071863174438, 1.7881393432617188e-07, 0.7071065902709961), (-0.8314700126647949, 1.7881393432617188e-07, 0.5555698871612549), (-0.923879861831665, 2.086162567138672e-07, 0.3826829195022583), (-0.9807853698730469, 2.2351741790771484e-07, 0.1950896978378296), (-1.0, 2.365559907957504e-07, -7.290432222362142e-07), (-0.9807850122451782, 2.5331974029541016e-07, -0.195091113448143), (-0.9238790273666382, 2.682209014892578e-07, -0.38268423080444336), (-0.831468939781189, 2.980232238769531e-07, -0.5555710196495056), (-0.7071058750152588, 2.980232238769531e-07, -0.707107424736023), (-0.555569052696228, 2.980232238769531e-07, -0.8314701318740845), (-0.38268208503723145, 2.980232238769531e-07, -0.923879861831665), (-0.19508881866931915, 2.980232238769531e-07, -0.9807853102684021), (1.6053570561780361e-06, 2.980232238769531e-07, -0.9999997615814209), (0.19509197771549225, 2.980232238769531e-07, -0.9807847142219543), (0.3826850652694702, 2.980232238769531e-07, -0.9238786101341248), (0.5555717945098877, 2.980232238769531e-07, -0.8314683437347412)]
verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v]
edges = [(28, 12), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
else:
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
return obj
else:
return None
def create_cube_widget(rig, bone_name, radius=0.5, bone_transform_name=None):
""" Creates a basic cube widget.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
r = radius
verts = [(r, r, r), (r, -r, r), (-r, -r, r), (-r, r, r), (r, r, -r), (r, -r, -r), (-r, -r, -r), (-r, r, -r)]
edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_chain_widget(rig, bone_name, radius=0.5, invert=False, bone_transform_name=None):
"""Creates a basic chain widget
"""
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
r = radius
rh = radius/2
if invert:
verts = [(rh, rh, rh), (r, -r, r), (-r, -r, r), (-rh, rh, rh), (rh, rh, -rh), (r, -r, -r), (-r, -r, -r), (-rh, rh, -rh)]
else:
verts = [(r, r, r), (rh, -rh, rh), (-rh, -rh, rh), (-r, r, r), (r, r, -r), (rh, -rh, -rh), (-rh, -rh, -rh), (-r, r, -r)]
edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_sphere_widget(rig, bone_name, bone_transform_name=None):
""" Creates a basic sphere widget, three pependicular overlapping circles.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
verts = [(0.3535533845424652, 0.3535533845424652, 0.0), (0.4619397521018982, 0.19134171307086945, 0.0), (0.5, -2.1855694143368964e-08, 0.0), (0.4619397521018982, -0.19134175777435303, 0.0), (0.3535533845424652, -0.3535533845424652, 0.0), (0.19134174287319183, -0.4619397521018982, 0.0), (7.549790126404332e-08, -0.5, 0.0), (-0.1913416087627411, -0.46193981170654297, 0.0), (-0.35355329513549805, -0.35355350375175476, 0.0), (-0.4619397521018982, -0.19134178757667542, 0.0), (-0.5, 5.962440319251527e-09, 0.0), (-0.4619397222995758, 0.1913418024778366, 0.0), (-0.35355326533317566, 0.35355350375175476, 0.0), (-0.19134148955345154, 0.46193987131118774, 0.0), (3.2584136988589307e-07, 0.5, 0.0), (0.1913420855998993, 0.46193960309028625, 0.0), (7.450580596923828e-08, 0.46193960309028625, 0.19134199619293213), (5.9254205098113744e-08, 0.5, 2.323586443253589e-07), (4.470348358154297e-08, 0.46193987131118774, -0.1913415789604187), (2.9802322387695312e-08, 0.35355350375175476, -0.3535533547401428), (2.9802322387695312e-08, 0.19134178757667542, -0.46193981170654297), (5.960464477539063e-08, -1.1151834122813398e-08, -0.5000000596046448), (5.960464477539063e-08, -0.1913418024778366, -0.46193984150886536), (5.960464477539063e-08, -0.35355350375175476, -0.3535533845424652), (7.450580596923828e-08, -0.46193981170654297, -0.19134166836738586), (9.348272556053416e-08, -0.5, 1.624372103492533e-08), (1.043081283569336e-07, -0.4619397521018982, 0.19134168326854706), (1.1920928955078125e-07, -0.3535533845424652, 0.35355329513549805), (1.1920928955078125e-07, -0.19134174287319183, 0.46193966269493103), (1.1920928955078125e-07, -4.7414250303745575e-09, 0.49999991059303284), (1.1920928955078125e-07, 0.19134172797203064, 0.46193966269493103), (8.940696716308594e-08, 0.3535533845424652, 0.35355329513549805), (0.3535534739494324, 0.0, 0.35355329513549805), (0.1913418173789978, -2.9802322387695312e-08, 0.46193966269493103), (8.303572940349113e-08, -5.005858838558197e-08, 0.49999991059303284), (-0.19134165346622467, -5.960464477539063e-08, 0.46193966269493103), (-0.35355329513549805, -8.940696716308594e-08, 0.35355329513549805), (-0.46193963289260864, -5.960464477539063e-08, 0.19134168326854706), (-0.49999991059303284, -5.960464477539063e-08, 1.624372103492533e-08), (-0.4619397521018982, -2.9802322387695312e-08, -0.19134166836738586), (-0.3535534143447876, -2.9802322387695312e-08, -0.3535533845424652), (-0.19134171307086945, 0.0, -0.46193984150886536), (7.662531942287387e-08, 9.546055501630235e-09, -0.5000000596046448), (0.19134187698364258, 5.960464477539063e-08, -0.46193981170654297), (0.3535535931587219, 5.960464477539063e-08, -0.3535533547401428), (0.4619399905204773, 5.960464477539063e-08, -0.1913415789604187), (0.5000000596046448, 5.960464477539063e-08, 2.323586443253589e-07), (0.4619396924972534, 2.9802322387695312e-08, 0.19134199619293213)]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), (16, 31), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_limb_widget(rig, bone_name, bone_transform_name=None):
""" Creates a basic limb widget, a line that spans the length of the
bone, with a circle around the center.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
verts = [(-1.1920928955078125e-07, 1.7881393432617188e-07, 0.0), (3.5762786865234375e-07, 1.0000004768371582, 0.0), (0.1767769455909729, 0.5000001192092896, 0.17677664756774902), (0.20786768198013306, 0.5000001192092896, 0.1388925313949585), (0.23097014427185059, 0.5000001192092896, 0.09567084908485413), (0.24519658088684082, 0.5000001192092896, 0.048772573471069336), (0.2500002384185791, 0.5000001192092896, -2.545945676502015e-09), (0.24519658088684082, 0.5000001192092896, -0.048772573471069336), (0.23097014427185059, 0.5000001192092896, -0.09567084908485413), (0.20786768198013306, 0.5000001192092896, -0.13889259099960327), (0.1767769455909729, 0.5000001192092896, -0.1767767071723938), (0.13889282941818237, 0.5000001192092896, -0.20786744356155396), (0.09567105770111084, 0.5000001192092896, -0.23096990585327148), (0.04877278208732605, 0.5000001192092896, -0.24519634246826172), (1.7279069197684294e-07, 0.5000000596046448, -0.25), (-0.0487724244594574, 0.5000001192092896, -0.24519634246826172), (-0.09567070007324219, 0.5000001192092896, -0.2309698462486267), (-0.13889241218566895, 0.5000001192092896, -0.20786738395690918), (-0.17677652835845947, 0.5000001192092896, -0.17677664756774902), (-0.20786726474761963, 0.5000001192092896, -0.13889244198799133), (-0.23096972703933716, 0.5000001192092896, -0.09567070007324219), (-0.24519610404968262, 0.5000001192092896, -0.04877239465713501), (-0.2499997615814209, 0.5000001192092896, 2.1997936983098043e-07), (-0.24519598484039307, 0.5000001192092896, 0.04877282679080963), (-0.23096948862075806, 0.5000001192092896, 0.09567108750343323), (-0.20786696672439575, 0.5000001192092896, 0.1388927698135376), (-0.1767762303352356, 0.5000001192092896, 0.17677688598632812), (-0.13889199495315552, 0.5000001192092896, 0.2078675627708435), (-0.09567028284072876, 0.5000001192092896, 0.23097002506256104), (-0.048771947622299194, 0.5000001192092896, 0.24519634246826172), (6.555903269145347e-07, 0.5000001192092896, 0.25), (0.04877324402332306, 0.5000001192092896, 0.24519622325897217), (0.09567153453826904, 0.5000001192092896, 0.23096966743469238), (0.13889318704605103, 0.5000001192092896, 0.20786714553833008)]
edges = [(0, 1), (2, 3), (4, 3), (5, 4), (5, 6), (6, 7), (8, 7), (8, 9), (10, 9), (10, 11), (11, 12), (13, 12), (14, 13), (14, 15), (16, 15), (16, 17), (17, 18), (19, 18), (19, 20), (21, 20), (21, 22), (22, 23), (24, 23), (25, 24), (25, 26), (27, 26), (27, 28), (29, 28), (29, 30), (30, 31), (32, 31), (32, 33), (2, 33)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_bone_widget(rig, bone_name, bone_transform_name=None):
""" Creates a basic bone widget, a simple obolisk-esk shape.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
verts = [(0.04, 1.0, -0.04), (0.1, 0.0, -0.1), (-0.1, 0.0, -0.1), (-0.04, 1.0, -0.04), (0.04, 1.0, 0.04), (0.1, 0.0, 0.1), (-0.1, 0.0, 0.1), (-0.04, 1.0, 0.04)]
edges = [(1, 2), (0, 1), (0, 3), (2, 3), (4, 5), (5, 6), (6, 7), (4, 7), (1, 5), (0, 4), (2, 6), (3, 7)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_compass_widget(rig, bone_name, bone_transform_name=None):
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
verts = [(0.0, 1.2000000476837158, 0.0), (0.19509032368659973, 0.9807852506637573, 0.0), (0.3826834559440613, 0.9238795042037964, 0.0), (0.5555702447891235, 0.8314695954322815, 0.0), (0.7071067690849304, 0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (1.2000000476837158, 7.549790126404332e-08, 0.0), (0.9807853102684021, -0.19509020447731018, 0.0), (0.9238795638084412, -0.38268327713012695, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (0.5555701851844788, -0.8314696550369263, 0.0), (0.38268327713012695, -0.9238796234130859, 0.0), (0.19509008526802063, -0.9807853102684021, 0.0), (-3.2584136988589307e-07, -1.2999999523162842, 0.0), (-0.19509072601795197, -0.9807851910591125, 0.0), (-0.3826838731765747, -0.9238793253898621, 0.0), (-0.5555707216262817, -0.8314692974090576, 0.0), (-0.7071072459220886, -0.707106351852417, 0.0), (-0.8314700126647949, -0.5555696487426758, 0.0), (-0.923879861831665, -0.3826826810836792, 0.0), (-0.9807854294776917, -0.1950894594192505, 0.0), (-1.2000000476837158, 9.655991561885457e-07, 0.0), (-0.980785071849823, 0.1950913518667221, 0.0), (-0.923879086971283, 0.38268446922302246, 0.0), (-0.831468939781189, 0.5555712580680847, 0.0), (-0.7071058750152588, 0.707107663154602, 0.0), (-0.5555691123008728, 0.8314703702926636, 0.0), (-0.38268208503723145, 0.9238801002502441, 0.0), (-0.19508881866931915, 0.9807855486869812, 0.0)]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_root_widget(rig, bone_name, bone_transform_name=None):
""" Creates a widget for the root bone.
"""
obj = create_widget(rig, bone_name, bone_transform_name)
verts = [(0.7071067690849304, 0.7071067690849304, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (-0.7071067690849304, 0.7071067690849304, 0.0), (-0.7071067690849304, -0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (-0.8314696550369263, 0.5555701851844788, 0.0), (-0.8314696550369263, -0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9238795042037964, -0.3826834261417389, 0.0), (-0.9238795042037964, 0.3826834261417389, 0.0), (-0.9238795042037964, -0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (0.9807852506637573, -0.19509035348892212, 0.0), (-0.9807852506637573, 0.19509035348892212, 0.0), (-0.9807852506637573, -0.19509035348892212, 0.0), (0.19509197771549225, 0.9807849526405334, 0.0), (0.19509197771549225, -0.9807849526405334, 0.0), (-0.19509197771549225, 0.9807849526405334, 0.0), (-0.19509197771549225, -0.9807849526405334, 0.0), (0.3826850652694702, 0.9238788485527039, 0.0), (0.3826850652694702, -0.9238788485527039, 0.0), (-0.3826850652694702, 0.9238788485527039, 0.0), (-0.3826850652694702, -0.9238788485527039, 0.0), (0.5555717945098877, 0.8314685821533203, 0.0), (0.5555717945098877, -0.8314685821533203, 0.0), (-0.5555717945098877, 0.8314685821533203, 0.0), (-0.5555717945098877, -0.8314685821533203, 0.0), (0.19509197771549225, 1.2807848453521729, 0.0), (0.19509197771549225, -1.2807848453521729, 0.0), (-0.19509197771549225, 1.2807848453521729, 0.0), (-0.19509197771549225, -1.2807848453521729, 0.0), (1.280785322189331, 0.19509035348892212, 0.0), (1.280785322189331, -0.19509035348892212, 0.0), (-1.280785322189331, 0.19509035348892212, 0.0), (-1.280785322189331, -0.19509035348892212, 0.0), (0.3950919806957245, 1.2807848453521729, 0.0), (0.3950919806957245, -1.2807848453521729, 0.0), (-0.3950919806957245, 1.2807848453521729, 0.0), (-0.3950919806957245, -1.2807848453521729, 0.0), (1.280785322189331, 0.39509034156799316, 0.0), (1.280785322189331, -0.39509034156799316, 0.0), (-1.280785322189331, 0.39509034156799316, 0.0), (-1.280785322189331, -0.39509034156799316, 0.0), (0.0, 1.5807849168777466, 0.0), (0.0, -1.5807849168777466, 0.0), (1.5807852745056152, 0.0, 0.0), (-1.5807852745056152, 0.0, 0.0)]
edges = [(0, 4), (1, 5), (2, 6), (3, 7), (4, 8), (5, 9), (6, 10), (7, 11), (8, 12), (9, 13), (10, 14), (11, 15), (16, 20), (17, 21), (18, 22), (19, 23), (20, 24), (21, 25), (22, 26), (23, 27), (0, 24), (1, 25), (2, 26), (3, 27), (16, 28), (17, 29), (18, 30), (19, 31), (12, 32), (13, 33), (14, 34), (15, 35), (28, 36), (29, 37), (30, 38), (31, 39), (32, 40), (33, 41), (34, 42), (35, 43), (36, 44), (37, 45), (38, 44), (39, 45), (40, 46), (41, 46), (42, 47), (43, 47)]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
Lucio Rossi
committed
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
def create_neck_bend_widget(rig, bone_name, radius=1.0, head_tail=0.0, bone_transform_name=None):
obj = create_widget(rig, bone_name, bone_transform_name)
size = 2.0
if obj != None:
v = [(-0.08855080604553223 * size, 0.7388765811920166 * size, -0.3940150737762451 * size),
(0.08855044841766357 * size, 0.7388765811920166 * size, -0.3940150737762451 * size),
(0.17710095643997192 * size, 0.5611097812652588 * size, -0.6478927135467529 * size),
(-4.0892032870942785e-07 * size, 0.4087378978729248 * size, -0.865501880645752 * size),
(-0.17710143327713013 * size, 0.5611097812652588 * size, -0.6478922367095947 * size),
(0.08855026960372925 * size, 0.5611097812652588 * size, -0.6478924751281738 * size),
(-0.08855092525482178 * size, 0.5611097812652588 * size, -0.6478927135467529 * size),
(-0.6478927135467529 * size, 0.5611097812652588 * size, 0.08855098485946655 * size),
(-0.6478927135467529 * size, 0.5611097812652588 * size, -0.08855020999908447 * size),
(-0.6478924751281738 * size, 0.5611097812652588 * size, 0.17710155248641968 * size),
(-0.865501880645752 * size, 0.4087378978729248 * size, 4.6876743908796925e-07 * size),
(-0.647892951965332 * size, 0.5611097812652588 * size, -0.17710083723068237 * size),
(-0.39401543140411377 * size, 0.7388765811920166 * size, -0.08855029940605164 * size),
(-0.39401543140411377 * size, 0.7388765811920166 * size, 0.08855095505714417 * size),
(0.6478927135467529 * size, 0.5611097812652588 * size, -0.08855059742927551 * size),
(0.6478927135467529 * size, 0.5611097812652588 * size, 0.08855065703392029 * size),
(0.6478924751281738 * size, 0.5611097812652588 * size, -0.17710113525390625 * size),
(0.865501880645752 * size, 0.4087378978729248 * size, -3.264514703005261e-08 * size),
(0.647892951965332 * size, 0.5611097812652588 * size, 0.1771012544631958 * size),
(0.08855065703392029 * size, 0.7388765811920166 * size, 0.3940155506134033 * size),
(-0.08855056762695312 * size, 0.7388765811920166 * size, 0.3940155506134033 * size),
(-0.17710107564926147 * size, 0.5611097812652588 * size, 0.647892951965332 * size),
(2.244429140318971e-07 * size, 0.4087378978729248 * size, 0.865502119064331 * size),
(0.17710131406784058 * size, 0.5611097812652588 * size, 0.6478927135467529 * size),
(-0.08855044841766357 * size, 0.5611097812652588 * size, 0.647892951965332 * size),
(0.08855074644088745 * size, 0.5611097812652588 * size, 0.647892951965332 * size),
(0.3940153121948242 * size, 0.7388765811920166 * size, 0.08855071663856506 * size),
(0.39401519298553467 * size, 0.7388765811920166 * size, -0.08855047821998596 * size),
(-8.416645869147032e-08 * size, 0.8255770206451416 * size, -0.2656517028808594 * size),
(-0.06875583529472351 * size, 0.8255770206451416 * size, -0.2565997838973999 * size),
(-0.13282597064971924 * size, 0.8255770206451416 * size, -0.2300611138343811 * size),
(-0.18784427642822266 * size, 0.8255770206451416 * size, -0.18784409761428833 * size),
(-0.2300613522529602 * size, 0.8255770206451416 * size, -0.1328257918357849 * size),
(-0.256600022315979 * size, 0.8255770206451416 * size, -0.06875564157962799 * size),
(-0.2656519412994385 * size, 0.8255770206451416 * size, 9.328307726264029e-08 * size),
(-0.25660014152526855 * size, 0.8255770206451416 * size, 0.06875583529472351 * size),
(-0.2300613522529602 * size, 0.8255770206451416 * size, 0.13282597064971924 * size),
(-0.18784433603286743 * size, 0.8255770206451416 * size, 0.18784421682357788 * size),
(-0.1328260898590088 * size, 0.8255770206451416 * size, 0.23006129264831543 * size),
(-0.06875592470169067 * size, 0.8255770206451416 * size, 0.256600022315979 * size),
(-1.8761508613351907e-07 * size, 0.8255770206451416 * size, 0.2656519412994385 * size),
(0.06875556707382202 * size, 0.8255770206451416 * size, 0.2566000819206238 * size),
(0.13282573223114014 * size, 0.8255770206451416 * size, 0.23006141185760498 * size),
(0.18784403800964355 * size, 0.8255770206451416 * size, 0.1878443956375122 * size),
(0.23006105422973633 * size, 0.8255770206451416 * size, 0.1328260898590088 * size),
(0.25659990310668945 * size, 0.8255770206451416 * size, 0.06875596940517426 * size),
(0.2656517028808594 * size, 0.8255770206451416 * size, 2.3684407324253698e-07 * size),
(0.25659990310668945 * size, 0.8255770206451416 * size, -0.06875550746917725 * size),
(0.23006117343902588 * size, 0.8255770206451416 * size, -0.13282567262649536 * size),
(0.18784427642822266 * size, 0.8255770206451416 * size, -0.18784397840499878 * size),
(0.13282597064971924 * size, 0.8255770206451416 * size, -0.23006099462509155 * size),
(0.0687558501958847 * size, 0.8255770206451416 * size, -0.2565997838973999 * size), ]
edges = [(1, 0), (3, 2), (5, 2), (4, 3), (6, 4), (1, 5), (0, 6), (13, 7), (12, 8), (7, 9), (9, 10), (8, 11),
(27, 14), (26, 15), (14, 16), (16, 17), (15, 18), (17, 18), (10, 11), (12, 13), (20, 19), (22, 21),
(24, 21), (23, 22), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35),
(37, 36), (38, 37), (39, 38), (40, 39), (41, 40), (42, 41), (43, 42), (44, 43), (45, 44), (46, 45),
(47, 46), (48, 47), (49, 48), (50, 49), (51, 50), (28, 51), (26, 27), (25, 23), (20, 24),
(19, 25), ]
verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
def create_neck_tweak_widget(rig, bone_name, size=1.0, bone_transform_name=None):
obj = create_widget(rig, bone_name, bone_transform_name)
if obj != None:
verts = [(0.3535533845424652 * size, 0.3535533845424652 * size, 0.0 * size),
(0.4619397521018982 * size, 0.19134171307086945 * size, 0.0 * size),
(0.5 * size, -2.1855694143368964e-08 * size, 0.0 * size),
(0.4619397521018982 * size, -0.19134175777435303 * size, 0.0 * size),
(0.3535533845424652 * size, -0.3535533845424652 * size, 0.0 * size),
(0.19134174287319183 * size, -0.4619397521018982 * size, 0.0 * size),
(7.549790126404332e-08 * size, -0.5 * size, 0.0 * size),
(-0.1913416087627411 * size, -0.46193981170654297 * size, 0.0 * size),
(-0.35355329513549805 * size, -0.35355350375175476 * size, 0.0 * size),
(-0.4619397521018982 * size, -0.19134178757667542 * size, 0.0 * size),
(-0.5 * size, 5.962440319251527e-09 * size, 0.0 * size),
(-0.4619397222995758 * size, 0.1913418024778366 * size, 0.0 * size),
(-0.35355326533317566 * size, 0.35355350375175476 * size, 0.0 * size),
(-0.19134148955345154 * size, 0.46193987131118774 * size, 0.0 * size),
(3.2584136988589307e-07 * size, 0.5 * size, 0.0 * size),
(0.1913420855998993 * size, 0.46193960309028625 * size, 0.0 * size),
(7.450580596923828e-08 * size, 0.46193960309028625 * size, 0.19134199619293213 * size),
(5.9254205098113744e-08 * size, 0.5 * size, 2.323586443253589e-07 * size),
(4.470348358154297e-08 * size, 0.46193987131118774 * size, -0.1913415789604187 * size),
(2.9802322387695312e-08 * size, 0.35355350375175476 * size, -0.3535533547401428 * size),
(2.9802322387695312e-08 * size, 0.19134178757667542 * size, -0.46193981170654297 * size),
(5.960464477539063e-08 * size, -1.1151834122813398e-08 * size, -0.5000000596046448 * size),
(5.960464477539063e-08 * size, -0.1913418024778366 * size, -0.46193984150886536 * size),
(5.960464477539063e-08 * size, -0.35355350375175476 * size, -0.3535533845424652 * size),
(7.450580596923828e-08 * size, -0.46193981170654297 * size, -0.19134166836738586 * size),
(9.348272556053416e-08 * size, -0.5 * size, 1.624372103492533e-08 * size),
(1.043081283569336e-07 * size, -0.4619397521018982 * size, 0.19134168326854706 * size),
(1.1920928955078125e-07 * size, -0.3535533845424652 * size, 0.35355329513549805 * size),
(1.1920928955078125e-07 * size, -0.19134174287319183 * size, 0.46193966269493103 * size),
(1.1920928955078125e-07 * size, -4.7414250303745575e-09 * size, 0.49999991059303284 * size),
(1.1920928955078125e-07 * size, 0.19134172797203064 * size, 0.46193966269493103 * size),
(8.940696716308594e-08 * size, 0.3535533845424652 * size, 0.35355329513549805 * size),
(0.3535534739494324 * size, 0.0 * size, 0.35355329513549805 * size),
(0.1913418173789978 * size, -2.9802322387695312e-08 * size, 0.46193966269493103 * size),
(8.303572940349113e-08 * size, -5.005858838558197e-08 * size, 0.49999991059303284 * size),
(-0.19134165346622467 * size, -5.960464477539063e-08 * size, 0.46193966269493103 * size),
(-0.35355329513549805 * size, -8.940696716308594e-08 * size, 0.35355329513549805 * size),
(-0.46193963289260864 * size, -5.960464477539063e-08 * size, 0.19134168326854706 * size),
(-0.49999991059303284 * size, -5.960464477539063e-08 * size, 1.624372103492533e-08 * size),
(-0.4619397521018982 * size, -2.9802322387695312e-08 * size, -0.19134166836738586 * size),
(-0.3535534143447876 * size, -2.9802322387695312e-08 * size, -0.3535533845424652 * size),
(-0.19134171307086945 * size, 0.0 * size, -0.46193984150886536 * size),
(7.662531942287387e-08 * size, 9.546055501630235e-09 * size, -0.5000000596046448 * size),
(0.19134187698364258 * size, 5.960464477539063e-08 * size, -0.46193981170654297 * size),
(0.3535535931587219 * size, 5.960464477539063e-08 * size, -0.3535533547401428 * size),
(0.4619399905204773 * size, 5.960464477539063e-08 * size, -0.1913415789604187 * size),
(0.5000000596046448 * size, 5.960464477539063e-08 * size, 2.323586443253589e-07 * size),
(0.4619396924972534 * size, 2.9802322387695312e-08 * size, 0.19134199619293213 * size),
(1.563460111618042 * size, 2.778762819843905e-08 * size, 1.5634593963623047 * size),
(0.8461387157440186 * size, -1.0400220418205208e-07 * size, 2.0427582263946533 * size),
(7.321979467178608e-08 * size, -1.9357810288056498e-07 * size, 2.2110657691955566 * size),
(-0.8461385369300842 * size, -2.3579201524626114e-07 * size, 2.0427582263946533 * size),
(-1.5634597539901733 * size, -3.67581861837607e-07 * size, 1.5634593963623047 * size),
(-2.0427584648132324 * size, -2.3579204366797057e-07 * size, 0.8461383581161499 * size),
(-2.211066246032715 * size, -2.3579204366797057e-07 * size, 9.972505665700737e-08 * size),
(-2.0427589416503906 * size, -1.0400223260376151e-07 * size, -0.8461381196975708 * size),
(-1.5634604692459106 * size, -1.040022183929068e-07 * size, -1.563459873199463 * size),
(-0.8461387753486633 * size, 2.77876033294433e-08 * size, -2.042759418487549 * size),
(4.4872678017782164e-08 * size, 7.00015263532805e-08 * size, -2.211066484451294 * size),
(0.8461388349533081 * size, 2.913672290105751e-07 * size, -2.0427591800689697 * size),
(1.5634608268737793 * size, 2.9136725743228453e-07 * size, -1.563459873199463 * size),
(2.042759895324707 * size, 2.9136725743228453e-07 * size, -0.8461377024650574 * size),
(2.211066722869873 * size, 2.9136725743228453e-07 * size, 1.0554133496043505e-06 * size),
(2.0427587032318115 * size, 1.5957746768435754e-07 * size, 0.8461397886276245 * size), ]
edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11),
(11, 12), (12, 13), (13, 14), (14, 15), (0, 15), (16, 31), (16, 17), (17, 18), (18, 19), (19, 20),
(20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30),
(30, 31), (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), (40, 41),
(41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47), (48, 49), (49, 50), (50, 51),
(51, 52), (52, 53), (53, 54), (54, 55), (55, 56), (56, 57), (57, 58), (58, 59), (59, 60), (60, 61),
(61, 62), (62, 63), (48, 63), (21, 58), (10, 54), (29, 50), (2, 62), ]
mesh = obj.data
mesh.from_pydata(verts, edges, [])
mesh.update()
Nathan Vegdahl
committed
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
#=============================================
# Math
#=============================================
def angle_on_plane(plane, vec1, vec2):
""" Return the angle between two vectors projected onto a plane.
"""
plane.normalize()
vec1 = vec1 - (plane * (vec1.dot(plane)))
vec2 = vec2 - (plane * (vec2.dot(plane)))
vec1.normalize()
vec2.normalize()
# Determine the angle
angle = math.acos(max(-1.0, min(1.0, vec1.dot(vec2))))
if angle < 0.00001: # close enough to zero that sign doesn't matter
return angle
# Determine the sign of the angle
vec3 = vec2.cross(vec1)
vec3.normalize()
sign = vec3.dot(plane)
if sign >= 0:
sign = 1
else:
sign = -1
return angle * sign
def align_bone_roll(obj, bone1, bone2):
""" Aligns the roll of two bones.
"""
bone1_e = obj.data.edit_bones[bone1]
bone2_e = obj.data.edit_bones[bone2]
bone1_e.roll = 0.0
# Get the directions the bones are pointing in, as vectors
y1 = bone1_e.y_axis
x1 = bone1_e.x_axis
y2 = bone2_e.y_axis
x2 = bone2_e.x_axis
# Get the shortest axis to rotate bone1 on to point in the same direction as bone2
axis = y1.cross(y2)
axis.normalize()
# Angle to rotate on that shortest axis
angle = y1.angle(y2)
# Create rotation matrix to make bone1 point in the same direction as bone2
rot_mat = Matrix.Rotation(angle, 3, axis)
# Roll factor
x3 = rot_mat * x1
dot = x2 * x3
if dot > 1.0:
dot = 1.0
elif dot < -1.0:
dot = -1.0
roll = math.acos(dot)
# Set the roll
bone1_e.roll = roll
# Check if we rolled in the right direction
x3 = rot_mat * bone1_e.x_axis
check = x2 * x3
# If not, reverse
if check < 0.9999:
bone1_e.roll = -roll
def align_bone_x_axis(obj, bone, vec):
""" Rolls the bone to align its x-axis as closely as possible to
the given vector.
Must be in edit mode.
"""
bone_e = obj.data.edit_bones[bone]
vec = vec.cross(bone_e.y_axis)
vec.normalize()
dot = max(-1.0, min(1.0, bone_e.z_axis.dot(vec)))
angle = math.acos(dot)
bone_e.roll += angle
dot1 = bone_e.z_axis.dot(vec)
bone_e.roll -= angle * 2
dot2 = bone_e.z_axis.dot(vec)
if dot1 > dot2:
bone_e.roll += angle * 2
def align_bone_z_axis(obj, bone, vec):
""" Rolls the bone to align its z-axis as closely as possible to
the given vector.
Must be in edit mode.
"""
bone_e = obj.data.edit_bones[bone]
vec = bone_e.y_axis.cross(vec)
vec.normalize()
dot = max(-1.0, min(1.0, bone_e.x_axis.dot(vec)))
angle = math.acos(dot)
bone_e.roll += angle
dot1 = bone_e.x_axis.dot(vec)
bone_e.roll -= angle * 2
dot2 = bone_e.x_axis.dot(vec)
if dot1 > dot2:
bone_e.roll += angle * 2
def align_bone_y_axis(obj, bone, vec):
""" Matches the bone y-axis to
the given vector.
Must be in edit mode.
"""
bone_e = obj.data.edit_bones[bone]
vec.normalize()
vec = vec * bone_e.length
bone_e.tail = bone_e.head + vec
#=============================================
# Misc
#=============================================
def copy_attributes(a, b):
keys = dir(a)
for key in keys:
if not key.startswith("_") \
and not key.startswith("error_") \
and key != "is_valid" \
and key != "rna_type" \
and key != "bl_rna":
try:
setattr(b, key, getattr(a, key))
pass
def get_rig_type(rig_type):
""" Fetches a rig module by name, and returns it.
"""
name = ".%s.%s" % (RIG_DIR, rig_type)
submod = importlib.import_module(name, package=MODULE_NAME)
Lucio Rossi
committed
def get_metarig_module(metarig_name, path=METARIG_DIR):
""" Fetches a rig module by name, and returns it.
"""
Lucio Rossi
committed
name = ".%s.%s" % (path, metarig_name)
submod = importlib.import_module(name, package=MODULE_NAME)
return submod
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
def connected_children_names(obj, bone_name):
""" Returns a list of bone names (in order) of the bones that form a single
connected chain starting with the given bone as a parent.
If there is a connected branch, the list stops there.
"""
bone = obj.data.bones[bone_name]
names = []
while True:
connects = 0
con_name = ""
for child in bone.children:
if child.use_connect:
connects += 1
con_name = child.name
if connects == 1:
names += [con_name]
bone = obj.data.bones[con_name]
else:
break
return names
Nathan Vegdahl
committed
def has_connected_children(bone):
""" Returns true/false whether a bone has connected children or not.
"""
t = False
for b in bone.children:
t = t or b.use_connect
return t
def get_layers(layers):
""" Does it's best to exctract a set of layers from any data thrown at it.
"""
if type(layers) == int:
return [x == layers for x in range(0, 32)]
elif type(layers) == str:
s = layers.split(",")
l = []
for i in s:
try:
l += [int(float(i))]
except ValueError:
pass
return [x in l for x in range(0, 32)]
elif type(layers) == tuple or type(layers) == list:
return [x in layers for x in range(0, 32)]
else:
try:
list(layers)
except TypeError:
pass
else:
return [x in layers for x in range(0, 32)]
def write_metarig(obj, layers=False, func_name="create", groups=False):
Write a metarig as a python script, this rig is to have all info needed for
generating the real rig with rigify.
code.append("import bpy\n\n")
code.append("from mathutils import Color\n\n")
code.append("def %s(obj):" % func_name)
code.append(" # generated by rigify.utils.write_metarig")
bpy.ops.object.mode_set(mode='EDIT')
code.append(" bpy.ops.object.mode_set(mode='EDIT')")
code.append(" arm = obj.data")
arm = obj.data
# Rigify bone group colors info
if groups and len(arm.rigify_colors) > 0:
code.append("\n for i in range(" + str(len(arm.rigify_colors)) + "):")
code.append(" arm.rigify_colors.add()\n")
for i in range(len(arm.rigify_colors)):
name = arm.rigify_colors[i].name
active = arm.rigify_colors[i].active
normal = arm.rigify_colors[i].normal
select = arm.rigify_colors[i].select
standard_colors_lock = arm.rigify_colors[i].standard_colors_lock
code.append(' arm.rigify_colors[' + str(i) + '].name = "' + name + '"')
code.append(' arm.rigify_colors[' + str(i) + '].active = Color(' + str(active[:]) + ')')
code.append(' arm.rigify_colors[' + str(i) + '].normal = Color(' + str(normal[:]) + ')')
code.append(' arm.rigify_colors[' + str(i) + '].select = Color(' + str(select[:]) + ')')
code.append(' arm.rigify_colors[' + str(i) + '].standard_colors_lock = ' + str(standard_colors_lock))
# Rigify layer layout info
if layers and len(arm.rigify_layers) > 0:
code.append("\n for i in range(" + str(len(arm.rigify_layers)) + "):")
code.append(" arm.rigify_layers.add()\n")
for i in range(len(arm.rigify_layers)):