Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'rigify/rigs/experimental/super_chain.py')
-rw-r--r--rigify/rigs/experimental/super_chain.py1414
1 files changed, 1414 insertions, 0 deletions
diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
new file mode 100644
index 00000000..cff25f2a
--- /dev/null
+++ b/rigify/rigs/experimental/super_chain.py
@@ -0,0 +1,1414 @@
+import bpy
+from mathutils import Vector
+from math import pi
+from ...utils import copy_bone, flip_bone, put_bone, org, align_bone_y_axis, align_bone_x_axis, align_bone_z_axis
+from ...utils import strip_org, make_deformer_name, connected_children_names
+from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_chain_widget
+from ...utils import MetarigError, make_mechanism_name, create_cube_widget
+from rna_prop_ui import rna_idprop_ui_prop_get
+from ..limbs.limb_utils import get_bone_name
+
+script = """
+controls = [%s]
+torso = '%s'
+
+if is_selected( controls ):
+ layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
+ layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
+"""
+
+
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ """ A simplified version of the torso rig. Basically a connected-DEF chain of bones """
+
+ eb = obj.data.edit_bones
+
+ self.obj = obj
+ self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
+ self.params = params
+ self.spine_length = sum([eb[b].length for b in self.org_bones])
+ self.bbones = params.bbones
+
+ # Check if user provided the positions of the neck and pivot
+ # if params.neck_pos and params.pivot_pos:
+ # self.neck_pos = params.neck_pos
+ # self.pivot_pos = params.pivot_pos
+ # else:
+ # raise MetarigError(
+ # "RIGIFY ERROR: please specify neck and pivot bone positions"
+ # )
+ #
+ # # Check if neck is lower than pivot
+ # if params.neck_pos <= params.pivot_pos:
+ # raise MetarigError(
+ # "RIGIFY ERROR: Neck cannot be below or the same as pivot"
+ # )
+
+ # if params.control_num:
+ # self.control_num = params.control_num
+ # else:
+ # raise MetarigError(
+ # "RIGIFY ERROR: please specify number of controls"
+ # )
+ #
+ # if params.control_num > round(len(eb)/2):
+ # raise MetarigError(
+ # "RIGIFY ERROR: Number of controls must be <= number of bones/2"
+ # )
+
+ # TODO:
+ # Limit neck_pos prop to 1 --> num of bones - 1 (last is head)
+ # Limit pivot_pos prop to 2 --> num of bones (must leave place for lower torso)
+
+ # if params.tail_pos:
+ # self.tail_pos = params.tail_pos
+
+ # Assign values to tweak layers props if opted by user
+ if params.tweak_extra_layers:
+ self.tweak_layers = list(params.tweak_layers)
+ else:
+ self.tweak_layers = None
+
+ # Report error of user created less than the minimum of 4 bones for rig
+ # if len(self.org_bones) <= 4:
+ # raise MetarigError(
+ # "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
+ # )
+
+
+ # def build_bone_structure( self ):
+ # """ Divide meta-rig into lists of bones according to torso rig anatomy:
+ # Neck --> Upper torso --> Lower torso --> Tail (optional) """
+ #
+ # if self.pivot_pos and self.neck_pos:
+ #
+ # neck_index = self.neck_pos - 1
+ # pivot_index = self.pivot_pos - 1
+ #
+ # tail_index = 0
+ # if 'tail_pos' in dir(self):
+ # tail_index = self.tail_pos - 1
+ #
+ # neck_bones = self.org_bones[neck_index::]
+ # upper_torso_bones = self.org_bones[pivot_index:neck_index]
+ # lower_torso_bones = self.org_bones[tail_index:pivot_index]
+ #
+ # tail_bones = []
+ # if tail_index:
+ # tail_bones = self.org_bones[::tail_index+1]
+ #
+ # return {
+ # 'neck' : neck_bones,
+ # 'upper' : upper_torso_bones,
+ # 'lower' : lower_torso_bones,
+ # 'tail' : tail_bones
+ # }
+ #
+ # else:
+ # return 'ERROR'
+
+ def orient_bone( self, eb, axis, scale, reverse = False ):
+ v = Vector((0,0,0))
+
+ setattr(v,axis,scale)
+
+ if reverse:
+ tail_vec = v * self.obj.matrix_world
+ eb.head[:] = eb.tail
+ eb.tail[:] = eb.head + tail_vec
+ else:
+ tail_vec = v * self.obj.matrix_world
+ eb.tail[:] = eb.head + tail_vec
+
+ def create_pivot(self, bones=None, pivot=None):
+ """ Create the pivot control and mechanism bones """
+
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ if not pivot:
+ pivot = int(len(org_bones)/2)
+
+ pivot_name = org_bones[pivot]
+ if '.L' in pivot_name:
+ prefix = strip_org(org_bones[pivot]).split('.')[0] + '.L'
+ elif '.R' in pivot_name:
+ prefix = strip_org(org_bones[pivot]).split('.')[0] + '.R'
+ else:
+ prefix = strip_org(org_bones[pivot]).split('.')[0]
+
+ ctrl_name = get_bone_name(prefix, 'ctrl', 'pivot')
+ ctrl_name = copy_bone(self.obj, pivot_name, ctrl_name)
+ ctrl_eb = eb[ ctrl_name ]
+
+ self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 )
+
+ pivot_loc = eb[pivot_name].head + ((eb[pivot_name].tail - eb[pivot_name].head)/2)*(len(org_bones)%2)
+
+ put_bone( self.obj, ctrl_name, pivot_loc)
+
+ v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last
+ v.normalize()
+ v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v
+ v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain
+
+ if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03: #if v_point is too small it's not usable
+ v_point = eb[org_bones[0]].x_axis
+
+ if self.params.tweak_axis == 'auto':
+ align_bone_y_axis(self.obj, ctrl_name, v)
+ align_bone_z_axis(self.obj, ctrl_name, -v_point)
+ elif self.params.tweak_axis == 'x':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((1,0,0)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((0,0,1)))
+ elif self.params.tweak_axis == 'y':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((0,1,0)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0)))
+ elif self.params.tweak_axis == 'z':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((0,0,1)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0)))
+
+ return {
+ 'ctrl' : ctrl_name
+ }#Todo modify following
+
+
+ org_bones = self.org_bones
+ pivot_name = org_bones[pivot-1]
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create torso control bone
+ torso_name = 'torso'
+ ctrl_name = copy_bone(self.obj, pivot_name, torso_name)
+ ctrl_eb = eb[ctrl_name]
+
+ self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 )
+
+ # Create mch_pivot
+ mch_name = make_mechanism_name( 'pivot' )
+ mch_name = copy_bone(self.obj, ctrl_name, mch_name)
+ mch_eb = eb[mch_name]
+
+ mch_eb.length /= 4
+
+ # Positioning pivot in a more usable location for animators
+ if hasattr(self, 'tail_pos') and self.tail_pos > 0:
+ pivot_loc = eb[org_bones[pivot-1]].head
+ else:
+ pivot_loc = (eb[org_bones[0]].head + eb[org_bones[0]].tail) / 2
+
+ put_bone(self.obj, ctrl_name, pivot_loc)
+
+ return {
+ 'ctrl': ctrl_name,
+ 'mch': mch_name
+ }
+
+ def create_deform(self):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ def_bones = []
+ for o in org_bones:
+ def_name = make_deformer_name(strip_org(o))
+ def_name = copy_bone(self.obj, o, def_name)
+ def_bones.append(def_name)
+
+ bpy.ops.object.mode_set(mode='POSE')
+ # Create bbone segments
+ for bone in def_bones:
+ self.obj.data.bones[bone].bbone_segments = self.bbones
+
+ if not self.SINGLE_BONE:
+ self.obj.data.bones[def_bones[0]].bbone_in = 0.0
+ self.obj.data.bones[def_bones[-1]].bbone_out = 0.0
+ else:
+ self.obj.data.bones[def_bones[0]].bbone_in = 1.0
+ self.obj.data.bones[def_bones[-1]].bbone_out = 1.0
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ return def_bones
+
+ def create_neck( self, neck_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create neck control
+ neck = copy_bone( self.obj, org(neck_bones[0]), 'neck' )
+ neck_eb = eb[ neck ]
+
+ # Neck spans all neck bones (except head)
+ neck_eb.tail[:] = eb[ org(neck_bones[-1]) ].head
+
+ # Create head control
+ head = copy_bone( self.obj, org(neck_bones[-1]), 'head' )
+
+ # MCH bones
+ # Neck MCH stretch
+ mch_str = copy_bone( self.obj, neck, make_mechanism_name('STR-neck') )
+
+ # Neck MCH rotation
+ mch_neck = copy_bone(
+ self.obj, neck, make_mechanism_name('ROT-neck')
+ )
+
+ self.orient_bone( eb[mch_neck], 'y', self.spine_length / 10 )
+
+ # Head MCH rotation
+ mch_head = copy_bone(
+ self.obj, head, make_mechanism_name('ROT-head')
+ )
+
+ self.orient_bone( eb[mch_head], 'y', self.spine_length / 10 )
+
+ twk,mch = [],[]
+
+ # Intermediary bones
+ for b in neck_bones[1:-1]: # All except 1st neck and (last) head
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ eb[mch_name].length /= 4
+
+ mch += [ mch_name ]
+
+ # Tweak bones
+ for b in neck_bones[:-1]: # All except last bone
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org(b), twk_name )
+
+ eb[twk_name].length /= 2
+
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl_neck' : neck,
+ 'ctrl' : head,
+ 'mch_str' : mch_str,
+ 'mch_neck' : mch_neck,
+ 'mch_head' : mch_head,
+ 'mch' : mch,
+ 'tweak' : twk
+ }
+
+ def create_chest( self, chest_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # get total spine length
+
+ # Create chest control bone
+ chest = copy_bone( self.obj, org( chest_bones[0] ), 'chest' )
+ self.orient_bone( eb[chest], 'y', self.spine_length / 3 )
+
+ # create chest mch_wgt
+ mch_wgt = copy_bone(
+ self.obj, org( chest_bones[-1] ),
+ make_mechanism_name( 'WGT-chest' )
+ )
+
+ # Create mch and twk bones
+ twk,mch = [],[]
+
+ for b in chest_bones:
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ self.orient_bone( eb[mch_name], 'y', self.spine_length / 10 )
+
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org(b), twk_name )
+ eb[twk_name].length /= 2
+
+ mch += [ mch_name ]
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl' : chest,
+ 'mch' : mch,
+ 'tweak' : twk,
+ 'mch_wgt' : mch_wgt
+ }
+
+ def create_hips( self, hip_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create hips control bone
+ hips = copy_bone( self.obj, org( hip_bones[-1] ), 'hips' )
+ self.orient_bone(
+ eb[hips],
+ 'y',
+ self.spine_length / 4,
+ reverse = True
+ )
+
+ # create hips mch_wgt
+ mch_wgt = copy_bone(
+ self.obj, org( hip_bones[0] ),
+ make_mechanism_name( 'WGT-hips' )
+ )
+
+ # Create mch and tweak bones
+ twk,mch = [],[]
+ for b in hip_bones:
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ self.orient_bone(
+ eb[mch_name], 'y', self.spine_length / 10, reverse = True
+ )
+
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org( b ), twk_name )
+
+ eb[twk_name].length /= 2
+
+ mch += [ mch_name ]
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl' : hips,
+ 'mch' : mch,
+ 'tweak' : twk,
+ 'mch_wgt' : mch_wgt
+ }
+
+ def create_tail( self, tail_bones ):
+ pass
+
+ def create_chain(self):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ twk, mch, mch_ctrl, ctrl = [], [], [], []
+
+ suffix = ''
+ if '.L' in org_bones[0]:
+ suffix = '.L'
+ elif '.R' in org_bones[0]:
+ suffix = '.R'
+
+ mch_auto = ''
+ if not self.SINGLE_BONE:
+ mch_name = copy_bone( self.obj, org(org_bones[0]), 'MCH-AUTO-'+strip_org(org_bones[0]).split('.')[0] + suffix)
+ eb[mch_name].head = eb[org_bones[0]].head
+ eb[mch_name].tail = eb[org_bones[-1]].tail
+
+ mch_auto = mch_name
+
+ # Intermediary bones
+ for b in org_bones: # All
+
+ if self.SINGLE_BONE:
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+ put_bone(self.obj, mch_name, eb[b].head - (eb[mch_name].tail - eb[mch_name].head))
+ align_bone_z_axis(self.obj, mch_name, eb[b].z_axis)
+ if '.' in mch_name:
+ mch_rev_name = mch_name.split('.')[0] + '_reverse.' + mch_name.split('.')[1]
+ else:
+ mch_rev_name = mch_name + '_reverse'
+ mch_rev_name = copy_bone(self.obj, org(b), mch_rev_name)
+ eb[mch_rev_name].length /= 4
+ eb[mch_rev_name].tail = eb[mch_name].head
+ align_bone_z_axis(self.obj, mch_rev_name, eb[b].z_axis)
+ mch += [mch_name]
+ mch += [mch_rev_name]
+ break
+
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+
+ mch += [ mch_name ]
+
+ if b == org_bones[-1]: #Add extra
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+ put_bone(self.obj, mch_name, eb[b].tail)
+ mch += [ mch_name ]
+
+ # Tweak & Ctrl bones
+ v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last
+ v.normalize()
+ v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v
+ v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain
+
+ if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03:
+ v_point = eb[org_bones[0]].x_axis
+
+ for b in org_bones: # All
+
+ suffix = ''
+ if '.L' in b:
+ suffix = '.L'
+ elif '.R' in b:
+ suffix = '.R'
+
+ if b == org_bones[0]:
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl')
+ name = copy_bone(self.obj, org(b), name)
+ align_bone_x_axis(self.obj, name, eb[org(b)].x_axis)
+ ctrl += [name]
+ else:
+ name = get_bone_name(b, 'ctrl', 'tweak')
+ name = copy_bone(self.obj, org(b), name)
+ twk += [name]
+
+ self.orient_bone(eb[name], 'y', eb[name].length / 2)
+
+ if self.params.tweak_axis == 'auto':
+ align_bone_y_axis(self.obj, name, v)
+ align_bone_z_axis(self.obj, name, -v_point) # invert?
+ elif self.params.tweak_axis == 'x':
+ align_bone_y_axis(self.obj, name, Vector((1,0,0)))
+ align_bone_x_axis(self.obj, name, Vector((0,0,1)))
+ elif self.params.tweak_axis == 'y':
+ align_bone_y_axis(self.obj, name, Vector((0,1,0)))
+ align_bone_x_axis(self.obj, name, Vector((1,0,0)))
+ elif self.params.tweak_axis == 'z':
+ align_bone_y_axis(self.obj, name, Vector((0,0,1)))
+ align_bone_x_axis(self.obj, name, Vector((1,0,0)))
+
+ if b == org_bones[-1]: # Add extra
+ ctrl_name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl')
+ ctrl_name = copy_bone(self.obj, org(b), ctrl_name)
+
+ self.orient_bone(eb[ctrl_name], 'y', eb[ctrl_name].length / 2)
+
+ #TODO check this if else
+ if self.params.conv_bone:
+ align_bone_y_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].y_axis)
+ align_bone_x_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].x_axis)
+ align_bone_z_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].z_axis)
+
+ else:
+ if twk:
+ lastname = twk[-1]
+ else:
+ lastname = ctrl[-1]
+ align_bone_y_axis(self.obj, ctrl_name, eb[lastname].y_axis)
+ align_bone_x_axis(self.obj, ctrl_name, eb[lastname].x_axis)
+ put_bone(self.obj, ctrl_name, eb[b].tail)
+
+ ctrl += [ctrl_name]
+
+ conv_twk = ''
+ # Convergence tweak
+ if self.params.conv_bone:
+ conv_twk = get_bone_name(self.params.conv_bone, 'ctrl', 'tweak') #"tweak_" + self.params.conv_bone
+
+ if not(conv_twk in eb.keys()):
+ conv_twk = copy_bone( self.obj, org(self.params.conv_bone), conv_twk )
+
+ # Mch controls
+ suffix = ''
+ if '.L' in b:
+ suffix = '.L'
+ elif '.R' in b:
+ suffix = '.R'
+
+ for b in org_bones:
+ mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
+ mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name )
+
+ self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 )
+
+ if b == org_bones[0] or b == org_bones[-1]:
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b)
+ else:
+ name = get_bone_name(b, 'ctrl', 'tweak') #"tweak_" + strip_org(b)
+ # align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ # align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ if self.SINGLE_BONE:
+ align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis)
+
+ mch_ctrl += [mch_ctrl_name]
+
+ if b == org_bones[-1]: #Add extra
+ mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
+ mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name )
+
+ self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 )
+
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b)
+ #align_bone_y_axis(self.obj, mch_ctrl_name, -eb[name].z_axis)
+ align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ put_bone(self.obj, mch_ctrl_name, eb[b].tail)
+
+ if self.SINGLE_BONE:
+ align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis)
+
+ mch_ctrl += [mch_ctrl_name]
+
+ return {
+ 'mch' : mch,
+ 'mch_ctrl' : mch_ctrl,
+ 'mch_auto' : mch_auto,
+ 'tweak' : twk,
+ 'ctrl' : ctrl,
+ 'conv' : conv_twk
+ }
+
+ def parent_bones(self, bones):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Parent deform bones
+ for i, b in enumerate(bones['def']):
+ if i > 0: # For all bones but the first (which has no parent)
+ eb[b].parent = eb[bones['def'][i-1]] # to previous
+ eb[b].use_connect = True
+
+ # Todo check case when sup_chain is in bigger rig
+ eb[bones['def'][0]].parent = eb[bones['chain']['mch'][0]]
+
+ for i, twk in enumerate(bones['chain']['tweak']):
+ eb[ twk ].parent = eb[bones['chain']['mch_ctrl'][i+1]]
+ eb[ twk ].use_inherit_scale = False
+
+ eb[bones['chain']['ctrl'][0]].parent = eb[bones['chain']['mch_ctrl'][0]]
+ eb[bones['chain']['ctrl'][0]].use_inherit_scale = False
+ eb[bones['chain']['ctrl'][1]].parent = eb[bones['chain']['mch_ctrl'][-1]]
+ eb[bones['chain']['ctrl'][1]].use_inherit_scale = False
+
+
+ if 'pivot' in bones.keys():
+ eb[ bones['pivot']['ctrl'] ].use_inherit_scale = False
+
+ for i,mch in enumerate( bones['chain']['mch'] ):
+ if mch == bones['chain']['mch'][0]:
+ eb[ mch ].parent = eb[ bones['chain']['ctrl'][0] ]
+ elif mch == bones['chain']['mch'][-1]:
+ eb[ mch ].parent = eb[ bones['chain']['ctrl'][1] ]
+ else:
+ eb[ mch ].parent = eb[ bones['chain']['tweak'][i-1] ]
+
+ if 'parent' in bones.keys():
+ eb[bones['chain']['mch_auto']].parent = eb[bones['parent']]
+ eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['parent']]
+ eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['parent']]
+
+ for i, mch_ctrl in enumerate( bones['chain']['mch_ctrl'][1:-1] ):
+ eb[ mch_ctrl ].parent = eb[ bones['chain']['mch_auto'] ]
+
+ if 'pivot' in bones.keys():
+ eb[ bones['pivot']['ctrl'] ].parent = eb[ bones['chain']['mch_auto'] ]
+
+ if bones['chain']['conv']:
+ eb[ bones['chain']['tweak'][-1] ].parent = eb[ bones['chain']['conv'] ]
+
+ if self.SINGLE_BONE:
+ eb[bones['chain']['ctrl'][0]].parent = None
+ eb[bones['chain']['ctrl'][-1]].parent = None
+ eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['chain']['ctrl'][0]]
+ eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['chain']['ctrl'][-1]]
+ eb[bones['chain']['mch'][0]].parent = eb[bones['chain']['mch'][1]]
+ eb[bones['chain']['mch'][1]].parent = eb[bones['chain']['mch_ctrl'][0]]
+
+ return #TODO modify what follows
+
+ # Parent control bones
+ # Head control => MCH-rotation_head
+ eb[ bones['neck']['ctrl'] ].parent = eb[ bones['neck']['mch_head'] ]
+
+ # MCH stretch => neck ctrl
+ eb[ bones['neck']['mch_str'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
+
+ # Neck control => MCH-rotation_neck
+ eb[ bones['neck']['ctrl_neck'] ].parent = eb[ bones['neck']['mch_neck'] ]
+
+ # Parent hips and chest controls to torso
+ eb[ bones['chest']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
+ eb[ bones['hips']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
+
+ # Parent mch bones
+ # Neck mch
+ eb[ bones['neck']['mch_head'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
+
+ parent = eb[ bones['neck']['mch_str'] ]
+ for i,b in enumerate([ eb[n] for n in bones['neck']['mch'] ]):
+ b.parent = parent
+
+ # Chest mch bones and neck mch
+ chest_mch = bones['chest']['mch'] + [ bones['neck']['mch_neck'] ]
+ for i,b in enumerate(chest_mch):
+ if i == 0:
+ eb[b].parent = eb[ bones['pivot']['ctrl'] ]
+ else:
+ eb[b].parent = eb[ chest_mch[i-1] ]
+
+ # Hips mch bones
+ for i,b in enumerate( bones['hips']['mch'] ):
+ if i == len(bones['hips']['mch']) - 1:
+ eb[b].parent = eb[ bones['pivot']['ctrl'] ]
+ else:
+ eb[b].parent = eb[ bones['hips']['mch'][i+1] ]
+
+ # mch pivot
+ eb[ bones['pivot']['mch'] ].parent = eb[ bones['chest']['mch'][0] ]
+
+ # MCH widgets
+ eb[ bones['chest']['mch_wgt'] ].parent = eb[ bones['chest']['mch'][-1] ]
+ eb[ bones['hips' ]['mch_wgt'] ].parent = eb[ bones['hips' ]['mch'][0 ] ]
+
+ # Tweaks
+
+ # Neck tweaks
+ for i,twk in enumerate( bones['neck']['tweak'] ):
+ if i == 0:
+ eb[ twk ].parent = eb[ bones['neck']['ctrl_neck'] ]
+ else:
+ eb[ twk ].parent = eb[ bones['neck']['mch'][i-1] ]
+
+ # Chest tweaks
+ for twk,mch in zip( bones['chest']['tweak'], bones['chest']['mch'] ):
+ if bones['chest']['tweak'].index( twk ) == 0:
+ eb[ twk ].parent = eb[ bones['pivot']['mch'] ]
+ else:
+ eb[ twk ].parent = eb[ mch ]
+
+ # Hips tweaks
+ for i,twk in enumerate(bones['hips']['tweak']):
+ if i == 0:
+ eb[twk].parent = eb[ bones['hips']['mch'][i] ]
+ else:
+ eb[twk].parent = eb[ bones['hips']['mch'][i-1] ]
+
+ # Parent orgs to matching tweaks
+ tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
+
+ if 'tail' in bones.keys():
+ tweaks += bones['tail']['tweak']
+
+ for org, twk in zip( org_bones, tweaks ):
+ eb[ org ].parent = eb[ twk ]
+
+ def make_constraint(self, bone, constraint):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pb = self.obj.pose.bones
+
+ owner_pb = pb[bone]
+ const = owner_pb.constraints.new(constraint['constraint'])
+ const.target = self.obj
+
+ # filter contraint props to those that actually exist in the current
+ # type of constraint, then assign values to each
+ for p in [k for k in constraint.keys() if k in dir(const)]:
+ setattr(const, p, constraint[p])
+
+ def constrain_bones(self, bones):
+ # DEF bones
+
+ deform = bones['def']
+ mch = bones['chain']['mch']
+ mch_ctrl = bones['chain']['mch_ctrl']
+ ctrls = bones['chain']['ctrl']
+ tweaks = [ ctrls[0]] + bones['chain']['tweak'] + [ ctrls[-1] ]
+
+ # if 'conv' in bones['chain'].keys():
+ # conv_tweak = bones['chain']['conv']
+
+ for i, d in enumerate(deform):
+
+ if len(deform) > 1:
+ self.make_constraint(d, {
+ 'constraint': 'COPY_TRANSFORMS',
+ 'subtarget': mch[i],
+ 'owner_space': 'POSE',
+ 'target_space': 'POSE'
+ })
+
+ self.make_constraint(d, {
+ 'constraint': 'STRETCH_TO',
+ 'subtarget': tweaks[i+1]
+ })
+
+ if 'pivot' in bones.keys():
+ step = 2/(len(self.org_bones))
+ for i,b in enumerate(mch_ctrl):
+ xval = i*step
+ influence = 2*xval - xval**2 #parabolic influence of pivot
+ if (i != 0) and (i != len(mch_ctrl)-1):
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : bones['pivot']['ctrl'],
+ 'influence' : influence,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ # MCH-AUTO
+
+ mch_auto = bones['chain']['mch_auto']
+
+ if mch_auto:
+ self.make_constraint( mch_auto, {
+ 'constraint': 'COPY_LOCATION',
+ 'subtarget' : mch[0],
+ 'owner_space' : 'WORLD',
+ 'target_space' : 'WORLD'
+ } )
+
+ self.make_constraint( mch_auto, {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : tweaks[-1]
+ } )
+
+ # PIVOT CTRL
+
+ if 'pivot' in bones.keys():
+
+ pivot = bones['pivot']['ctrl']
+
+ self.make_constraint( pivot, {
+ 'constraint': 'COPY_ROTATION',
+ 'subtarget' : tweaks[0],
+ 'influence' : 0.33,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ self.make_constraint( pivot, {
+ 'constraint': 'COPY_ROTATION',
+ 'subtarget' : tweaks[-1],
+ 'influence' : 0.33,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ # MCH-CTRL
+
+ # for i, b in enumerate(mch_ctrl):
+ #
+ # if i != 0 and mch_ctrl[i] != mch_ctrl[-1]:
+ # self.make_constraint( b, {
+ # 'constraint' : 'COPY_TRANSFORMS',
+ # 'subtarget' : tweaks[i-1],
+ # 'influence' : 0.5,
+ # 'owner_space' : 'LOCAL',
+ # 'target_space' : 'LOCAL'
+ # } )
+ #
+ # self.make_constraint( b, {
+ # 'constraint' : 'COPY_TRANSFORMS',
+ # 'subtarget' : tweaks[i+1],
+ # 'influence' : 0.5,
+ # 'owner_space' : 'LOCAL',
+ # 'target_space' : 'LOCAL'
+ # } )
+
+ return #Todo mdify what follows
+
+ # head and neck MCH bones
+ for b in [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]:
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_ROTATION',
+ 'subtarget' : bones['pivot']['ctrl'],
+ } )
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_SCALE',
+ 'subtarget' : bones['pivot']['ctrl'],
+ } )
+
+ # Neck MCH Stretch
+ self.make_constraint( bones['neck']['mch_str'], {
+ 'constraint' : 'DAMPED_TRACK',
+ 'subtarget' : bones['neck']['ctrl'],
+ })
+
+ self.make_constraint( bones['neck']['mch_str'], {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : bones['neck']['ctrl'],
+ })
+
+ # Intermediary mch bones
+ intermediaries = [ bones['neck'], bones['chest'], bones['hips'] ]
+
+ if 'tail' in bones.keys():
+ intermediaries += bones['tail']
+
+ for i,l in enumerate(intermediaries):
+ mch = l['mch']
+ factor = float( 1 / len( l['tweak'] ) )
+
+ for j,b in enumerate(mch):
+ if i == 0:
+ nfactor = float( (j + 1) / len( mch ) )
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_ROTATION',
+ 'subtarget' : l['ctrl'],
+ 'influence' : nfactor
+ } )
+ else:
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : l['ctrl'],
+ 'influence' : factor,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+
+ # MCH pivot
+ self.make_constraint( bones['pivot']['mch'], {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : bones['hips']['mch'][-1],
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ })
+
+ # DEF bones
+ deform = bones['def']
+ tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
+
+ for d,t in zip(deform, tweaks):
+ tidx = tweaks.index(t)
+
+ self.make_constraint( d, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : t
+ })
+
+ if tidx != len(tweaks) - 1:
+ self.make_constraint( d, {
+ 'constraint' : 'DAMPED_TRACK',
+ 'subtarget' : tweaks[ tidx + 1 ],
+ })
+
+ self.make_constraint( d, {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : tweaks[ tidx + 1 ],
+ })
+
+ def stick_to_bendy_bones(self, bones):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ deform = bones['def']
+ pb = self.obj.pose.bones
+
+ if len(deform) > 1: # Only for single bone sup chain
+ return
+
+ def_pb = pb[deform[0]]
+ ctrl_start = pb[bones['chain']['ctrl'][0]]
+ ctrl_end = pb[bones['chain']['ctrl'][-1]]
+ mch_start = pb[bones['chain']['mch'][0]]
+ mch_end = pb[bones['chain']['mch_ctrl'][-1]]
+
+ if 'bbone_custom_handle_start' in dir(def_pb) and 'bbone_custom_handle_end' in dir(def_pb):
+ if not self.SINGLE_BONE:
+ def_pb.bbone_custom_handle_start = ctrl_start
+ def_pb.bbone_custom_handle_end = ctrl_end
+ else:
+ def_pb.bbone_custom_handle_start = mch_start
+ def_pb.bbone_custom_handle_end = mch_end
+ def_pb.use_bbone_custom_handles = True
+
+ def create_drivers(self, bones):
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ pb = self.obj.pose.bones
+
+ # Setting the torso's props
+ torso = pb[ bones['pivot']['ctrl'] ]
+
+ props = [ "head_follow", "neck_follow" ]
+ owners = [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]
+
+ for prop in props:
+ if prop == 'neck_follow':
+ torso[prop] = 0.5
+ else:
+ torso[prop] = 0.0
+
+ prop = rna_idprop_ui_prop_get( torso, prop, create=True )
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["description"] = prop
+
+ # driving the follow rotation switches for neck and head
+ for bone, prop, in zip( owners, props ):
+ # Add driver to copy rotation constraint
+ drv = pb[ bone ].constraints[ 0 ].driver_add("influence").driver
+ drv.type = 'AVERAGE'
+
+ var = drv.variables.new()
+ var.name = prop
+ var.type = "SINGLE_PROP"
+ var.targets[0].id = self.obj
+ var.targets[0].data_path = \
+ torso.path_from_id() + '['+ '"' + prop + '"' + ']'
+
+ drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
+
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
+ drv_modifier.coefficients[0] = 1.0
+ drv_modifier.coefficients[1] = -1.0
+
+ def locks_and_widgets(self, bones):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pb = self.obj.pose.bones
+
+ #Locks
+ mch_ctrl = bones['chain']['mch_ctrl']
+
+ for b in mch_ctrl:
+ pb[b].lock_rotation = False, False, False
+ pb[b].lock_location = False, False, False
+ pb[b].lock_scale = False, False, False
+
+ for b in bones['chain']['tweak']:
+ pb[b].lock_rotation = True, False, True
+
+ for b in bones['chain']['ctrl']:
+ pb[b].lock_rotation = True, False, True
+
+ if 'pivot' in bones.keys():
+ pb[bones['pivot']['ctrl']].lock_rotation = True, False, True
+
+ # Assigning a widget to main ctrl bone
+ if 'pivot' in bones.keys():
+ create_cube_widget(
+ self.obj,
+ bones['pivot']['ctrl'],
+ radius = 0.15,
+ bone_transform_name = None
+ )
+
+ for bone in bones['chain']['tweak']:
+ create_cube_widget(
+ self.obj,
+ bone,
+ radius = 0.2,
+ bone_transform_name = None
+ )
+
+ create_chain_widget(
+ self.obj,
+ bones['chain']['ctrl'][0],
+ invert = False,
+ radius = 0.3,
+ bone_transform_name = None
+ )
+
+ create_chain_widget(
+ self.obj,
+ bones['chain']['ctrl'][-1],
+ invert = True,
+ radius = 0.3,
+ bone_transform_name = None
+ )
+
+ if bones['chain']['conv']:
+ create_cube_widget(
+ self.obj,
+ bones['chain']['conv'],
+ radius = 0.5,
+ bone_transform_name = None
+ )
+
+ # Assigning layers to tweaks and ctrls
+ for bone in bones['chain']['tweak']:
+ if self.tweak_layers:
+ pb[bone].bone.layers = self.tweak_layers
+
+ # for bone in bones['chain']['ctrl']:
+ # if self.tweak_layers:
+ # pb[bone].bone.layers = self.tweak_layers
+
+
+ return
+
+
+ # Locks
+ tweaks = bones['neck']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['hips']['tweak']
+
+ if 'tail' in bones.keys():
+ tweaks += bones['tail']['tweak']
+
+ # Tweak bones locks
+ for bone in tweaks:
+ pb[bone].lock_rotation = True, False, True
+ pb[bone].lock_scale = False, True, False
+
+ # Widgets
+
+ # Assigning a widget to pivot bone
+ if 'pivot' in bones.keys():
+ create_cube_widget(
+ self.obj,
+ bones['pivot']['ctrl'],
+ radius = 0.5,
+ bone_transform_name = None
+ )
+
+ # Assigning widgets to control bones
+ gen_ctrls = [
+ bones['neck']['ctrl_neck'],
+ bones['chest']['ctrl'],
+ bones['hips']['ctrl']
+ ]
+
+ if 'tail' in bones.keys():
+ gen_ctrls += [ bones['tail']['ctrl'] ]
+
+ for bone in gen_ctrls:
+ create_circle_widget(
+ self.obj,
+ bone,
+ radius = 1.0,
+ head_tail = 0.5,
+ with_line = False,
+ bone_transform_name = None
+ )
+
+ # Head widget
+ create_circle_widget(
+ self.obj,
+ bones['neck']['ctrl'],
+ radius = 0.75,
+ head_tail = 1.0,
+ with_line = False,
+ bone_transform_name = None
+ )
+
+ # place widgets on correct bones
+ chest_widget_loc = pb[ bones['chest']['mch_wgt'] ]
+ pb[bones['chest']['ctrl'] ].custom_shape_transform = chest_widget_loc
+
+ hips_widget_loc = pb[bones['hips']['mch_wgt']]
+ if 'tail' in bones.keys():
+ hips_widget_loc = bones['def'][self.tail_pos - 1]
+
+ pb[ bones['hips']['ctrl'] ].custom_shape_transform = hips_widget_loc
+
+ # Assigning widgets to tweak bones and layers
+ for bone in tweaks:
+ create_sphere_widget(self.obj, bone, bone_transform_name=None)
+
+ if self.tweak_layers:
+ pb[bone].bone.layers = self.tweak_layers
+
+ def generate(self):
+
+ # Torso Rig Anatomy:
+ # Neck: all bones above neck point, last bone is head
+ # Upper torso: all bones between pivot and neck start
+ # Lower torso: all bones below pivot until tail point
+ # Tail: all bones below tail point
+
+ #bone_chains = self.build_bone_structure()
+
+ self.SINGLE_BONE = (len(self.org_bones) == 1)
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ bones = {}
+ if eb[self.org_bones[0]].parent:
+ bones['parent'] = eb[self.org_bones[0]].parent.name
+
+ # Clear parents for org bones
+ for bone in self.org_bones[0:]:
+ eb[bone].use_connect = False
+ eb[bone].parent = None
+
+ #if bone_chains != 'ERROR':
+ #
+ # # Create lists of bones and strip "ORG" from their names
+ # neck_bones = [ strip_org(b) for b in bone_chains['neck' ] ]
+ # upper_torso_bones = [ strip_org(b) for b in bone_chains['upper'] ]
+ # lower_torso_bones = [ strip_org(b) for b in bone_chains['lower'] ]
+ # tail_bones = [ strip_org(b) for b in bone_chains['tail' ] ]
+
+ chain_bones = [strip_org(b) for b in self.org_bones]
+
+ # bones = {}
+ #
+ # bones['def'] = self.create_deform() # Gets org bones from self
+ # bones['pivot'] = self.create_pivot( self.pivot_pos )
+ # bones['neck'] = self.create_neck( neck_bones )
+ # bones['chest'] = self.create_chest( upper_torso_bones )
+ # bones['hips'] = self.create_hips( lower_torso_bones )
+ # # TODO: Add create tail
+ #
+ # if tail_bones:
+ # bones['tail'] = self.create_tail( tail_bones )
+
+
+
+ bones['def'] = self.create_deform()
+ if len(self.org_bones) > 2:
+ bones['pivot'] = self.create_pivot()
+ bones['chain'] = self.create_chain()
+
+ # Adjust Roll in SINGLE_BONE case
+ #if self.SINGLE_BONE:
+ all_bones = bones['chain']['mch'] + bones['chain']['mch_ctrl'] + bones['chain']['ctrl'] + bones['def']
+ for b in all_bones:
+ eb[b].roll = -pi / 2
+
+ #Todo create pivot-like controls
+
+ # # TEST
+ # bpy.ops.object.mode_set(mode ='EDIT')
+ # eb = self.obj.data.edit_bones
+ #
+ # self.parent_bones( bones )
+ # self.constrain_bones( bones )
+ # self.create_drivers( bones )
+ # self.locks_and_widgets( bones )
+
+ self.parent_bones(bones)
+ self.constrain_bones(bones)
+ self.stick_to_bendy_bones(bones)
+ self.locks_and_widgets(bones)
+
+ #Todo invoke the remaining functions
+
+ # controls = [ bones['neck']['ctrl'], bones['neck']['ctrl_neck'] ]
+ # controls += [ bones['chest']['ctrl'], bones['hips']['ctrl'] ]
+ # controls += [ bones['pivot']['ctrl'] ]
+
+ # if 'tail' in bones.keys():
+ # controls += [ bones['tail']['ctrl'] ]
+
+ return #TODO modify what follows
+
+ # Create UI
+ controls_string = ", ".join(["'" + x + "'" for x in controls]) #TODO correct this
+ return [script % (
+ controls_string,
+ bones['pivot']['ctrl'],
+ 'head_follow',
+ 'neck_follow'
+ )]
+
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+
+ items = [
+ ('auto', 'Auto', ''),
+ ('x', 'X', ''),
+ ('y', 'Y', ''),
+ ('z', 'Z', '')
+ ]
+
+ params.tweak_axis = bpy.props.EnumProperty(
+ items = items,
+ name = "Tweak Axis",
+ default = 'auto'
+ )
+
+ params.conv_bone = bpy.props.StringProperty(
+ name = 'Convergence bone',
+ default = ''
+ )
+
+ params.bbones = bpy.props.IntProperty(
+ name = 'bbone segments',
+ default = 10,
+ min = 1,
+ description = 'Number of segments'
+ )
+
+ # params.neck_pos = bpy.props.IntProperty(
+ # name = 'neck_position',
+ # default = 6,
+ # min = 0,
+ # description = 'Neck start position'
+ # )
+ #
+ # params.pivot_pos = bpy.props.IntProperty(
+ # name = 'pivot_position',
+ # default = 3,
+ # min = 0,
+ # description = 'Position of the torso control and pivot point'
+ # )
+ #
+ # params.tail_pos = bpy.props.IntProperty(
+ # name = 'tail_position',
+ # default = 0,
+ # min = 0,
+ # description = 'Where the tail starts (change from 0 to enable)'
+ # )
+
+ # Setting up extra layers for the FK and tweak
+ params.tweak_extra_layers = bpy.props.BoolProperty(
+ name = "tweak_extra_layers",
+ default = True,
+ description = ""
+ )
+
+ params.tweak_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters."""
+
+ # r = layout.row()
+ # r.prop(params, "neck_pos")
+ #
+ # r = layout.row()
+ # r.prop(params, "pivot_pos")
+ #
+ # r = layout.row()
+ # r.prop(params, "tail_pos")
+
+ # r = layout.row()
+ # r.prop(params, "control_num")
+
+ pb = bpy.context.object.pose
+
+ r = layout.row()
+ col = r.column(align=True)
+ row = col.row(align=True)
+ row.prop(params, "tweak_axis", expand=True)
+ # for i,axis in enumerate( [ 'x', 'y', 'z' ] ):
+ # row.prop(params, "tweak_axis", index=i, toggle=True, text=axis)
+
+ r = layout.row()
+ r.prop(params, "bbones")
+
+ r = layout.row()
+ r.prop_search(params, 'conv_bone', pb, "bones", text="Convergence Bone")
+
+ r = layout.row()
+ r.prop(params, "tweak_extra_layers")
+ r.active = params.tweak_extra_layers
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range(8):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range(16,24):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range(8,16):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range(24,32):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('spine')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.5000/8, 1.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['spine'] = bone.name
+ bone = arm.edit_bones.new('spine.001')
+ bone.head[:] = 0.0000, 0.5000/8, 1.0000/8
+ bone.tail[:] = 0.0000, 0.7500/8, 2.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine']]
+ bones['spine.001'] = bone.name
+ bone = arm.edit_bones.new('spine.002')
+ bone.head[:] = 0.0000, 0.7500/8, 2.0000/8
+ bone.tail[:] = 0.0000, 0.5000/8, 3.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine.001']]
+ bones['spine.002'] = bone.name
+ bone = arm.edit_bones.new('spine.003')
+ bone.head[:] = 0.0000, 0.5000/8, 3.0000/8
+ bone.tail[:] = 0.0000, 0.0000, 4.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine.002']]
+ bones['spine.003'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['spine']]
+ pbone.rigify_type = 'experimental.super_chain'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
+
+ arm.layers = [(x in [0]) for x in range(32)] \ No newline at end of file