From 5e7d0fc12643b7029fa2e2e7615d54cb1887d4b8 Mon Sep 17 00:00:00 2001 From: Lucio Rossi Date: Mon, 3 Oct 2016 20:31:57 +0200 Subject: Pitchipoy: added IK_follow on super_paw(s). Removed copy_trans constraint to parent target in case main limb bone has no parent --- rigify/rigs/pitchipoy/limbs/super_arm.py | 159 +++++++------------ rigify/rigs/pitchipoy/limbs/super_front_paw.py | 211 ++++++++++++++++++++----- rigify/rigs/pitchipoy/limbs/super_leg.py | 186 +++++++++------------- rigify/rigs/pitchipoy/limbs/super_rear_paw.py | 166 +++++++++++++++++-- 4 files changed, 459 insertions(+), 263 deletions(-) diff --git a/rigify/rigs/pitchipoy/limbs/super_arm.py b/rigify/rigs/pitchipoy/limbs/super_arm.py index 684241ee..1f84c6d5 100644 --- a/rigify/rigs/pitchipoy/limbs/super_arm.py +++ b/rigify/rigs/pitchipoy/limbs/super_arm.py @@ -18,7 +18,8 @@ ctrl = '%s' if is_selected( controls ): layout.prop( pose_bones[ ctrl ], '["%s"]') - layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) + if '%s' in pose_bones[ctrl].keys(): + layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) """ class Rig: @@ -47,8 +48,7 @@ class Rig: else: self.fk_layers = None - - def create_parent( self ): + def create_parent(self): org_bones = self.org_bones @@ -102,8 +102,7 @@ class Rig: return mch - - def create_tweak( self ): + def create_tweak(self): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -228,8 +227,7 @@ class Rig: return tweaks - - def create_def( self, tweaks ): + def create_def(self, tweaks): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -335,8 +333,7 @@ class Rig: return def_bones - - def create_ik( self, parent ): + def create_ik(self, parent): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -393,8 +390,7 @@ class Rig: 'mch_str' : mch_str } - - def create_fk( self, parent ): + def create_fk(self, parent): org_bones = self.org_bones.copy() @@ -443,8 +439,7 @@ class Rig: return { 'ctrl' : ctrls, 'mch' : mch } - - def org_parenting_and_switch( self, org, ik, fk, parent ): + def org_parenting_and_switch(self, org, ik, fk, parent): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones # re-parent ORGs in a connected chain @@ -492,8 +487,7 @@ class Rig: var.targets[0].data_path = \ pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - - def create_arm( self, bones ): + def create_arm( self, bones): org_bones = self.org_bones bpy.ops.object.mode_set(mode='EDIT') @@ -523,45 +517,29 @@ class Rig: eb[ctrl_root].use_connect = False eb[ctrl_root].parent = eb['root'] - ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) - eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) - eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent + if eb[org_bones[0]].parent: + arm_parent = eb[org_bones[0]].parent + ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) + eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) + eb[ctrl_parent].use_connect = False + eb[ctrl_parent].parent = eb[org_bones[0]].parent + else: + arm_parent = None # Set up constraints # Constrain ik ctrl to root / parent - # Todo this should be better : target = strip_org(eb[org_bones[0]].parent.name) - #target = eb[org_bones[0]].parent.name - make_constraint( self, ctrl_socket, { 'constraint' : 'COPY_TRANSFORMS', 'subtarget' : ctrl_root, }) - make_constraint( self, ctrl_socket, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : ctrl_parent, - }) - - # make_constraint( self, ctrl, { - # 'constraint' : 'CHILD_OF', - # 'subtarget' : 'root', - # }) - # - # - # make_constraint( self, ctrl, { - # 'constraint' : 'CHILD_OF', - # 'subtarget' : target, - # 'influence' : 0.0, - # }) - - - # pbone = self.obj.pose.bones[target] #SET INVERSE EMULATION - # - # const = self.obj.pose.bones[ctrl].constraints[1] - # const.inverse_matrix = (self.obj.matrix_world*pbone.matrix).inverted() + if arm_parent: + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_parent, + }) # Constrain mch target bone to the ik control and mch stretch @@ -630,19 +608,13 @@ class Rig: create_hand_widget(self.obj, ctrl, bone_transform_name=None) bones['ik']['ctrl']['terminal'] = [ ctrl ] - bones['ik']['mch_hand'] = [ctrl_socket, ctrl_root, ctrl_parent] + if arm_parent: + bones['ik']['mch_hand'] = [ctrl_socket, ctrl_root, ctrl_parent] + else: + bones['ik']['mch_hand'] = [ctrl_socket, ctrl_root] return bones - # def create_terminal( self, limb_type, bones ): - # if limb_type == 'arm': - # return create_arm( self, bones ) - # elif limb_type == 'leg': - # return create_leg( self, bones ) - # elif limb_type == 'paw': - # return create_paw( self, bones ) - - def create_drivers(self, bones): bpy.ops.object.mode_set(mode ='OBJECT') @@ -678,24 +650,25 @@ class Rig: drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 - drv = ctrl.constraints[ 1 ].driver_add("mute").driver - drv.type = 'AVERAGE' + if len(ctrl.constraints) > 1: + drv = ctrl.constraints[ 1 ].driver_add("mute").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 = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + 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 + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 - else: + elif len(ctrl.constraints) > 1: ctrl[prop]=0.0 rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) rna_prop["min"] = 0.0 @@ -704,22 +677,22 @@ class Rig: rna_prop["soft_max"] = 1.0 rna_prop["description"] = prop - drv = ctrl.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 = \ - ctrl.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 + # drv = ctrl.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 = \ + # ctrl.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 drv = ctrl.constraints[ 1 ].driver_add("influence").driver drv.type = 'AVERAGE' @@ -731,8 +704,7 @@ class Rig: var.targets[0].data_path = \ ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - - def generate( self ): + def generate(self): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones @@ -764,27 +736,16 @@ class Rig: controls_string = ", ".join(["'" + x + "'" for x in controls]) script = create_script( bones, 'arm' ) - script += extra_script % (controls_string, bones['ik']['mch_hand'][0], 'IK_follow', 'root/parent') + script += extra_script % (controls_string, bones['ik']['mch_hand'][0], 'IK_follow', 'root/parent', 'root/parent') return [ script ] -def add_parameters( params ): +def add_parameters(params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ - # items = [ - # ('arm', 'Arm', ''), - # ('leg', 'Leg', ''), - # ('paw', 'Paw', '') - # ] - # params.limb_type = bpy.props.EnumProperty( - # items = items, - # name = "Limb Type", - # default = 'arm' - # ) - items = [ ('x', 'X', ''), ('y', 'Y', ''), diff --git a/rigify/rigs/pitchipoy/limbs/super_front_paw.py b/rigify/rigs/pitchipoy/limbs/super_front_paw.py index 936395ca..04e6280f 100644 --- a/rigify/rigs/pitchipoy/limbs/super_front_paw.py +++ b/rigify/rigs/pitchipoy/limbs/super_front_paw.py @@ -15,6 +15,17 @@ from ..super_widgets import create_ikarrow_widget from ..super_widgets import create_foot_widget, create_ballsocket_widget from math import trunc + +extra_script = """ +controls = [%s] +ctrl = '%s' + +if is_selected( controls ): + layout.prop( pose_bones[ ctrl ], '["%s"]') + if '%s' in pose_bones[ctrl].keys(): + layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) +""" + class Rig: def __init__(self, obj, bone_name, params): """ Initialize torso rig and key rig properties """ @@ -41,8 +52,7 @@ class Rig: else: self.fk_layers = None - - def create_parent( self ): + def create_parent(self): org_bones = self.org_bones @@ -96,8 +106,7 @@ class Rig: return mch - - def create_tweak( self ): + def create_tweak(self): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -235,8 +244,7 @@ class Rig: return tweaks - - def create_def( self, tweaks ): + def create_def(self, tweaks ): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -342,8 +350,7 @@ class Rig: return def_bones - - def create_ik( self, parent ): + def create_ik(self, parent ): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -400,8 +407,7 @@ class Rig: 'mch_str' : mch_str } - - def create_fk( self, parent ): + def create_fk(self, parent ): org_bones = self.org_bones.copy() @@ -452,8 +458,7 @@ class Rig: return { 'ctrl' : ctrls, 'mch' : mch } - - def org_parenting_and_switch( self, org, ik, fk, parent ): + def org_parenting_and_switch(self, org, ik, fk, parent): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones # re-parent ORGs in a connected chain @@ -501,13 +506,12 @@ class Rig: var.targets[0].data_path = \ pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - def create_paw( self, bones ): + org_bones = list( [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) ) - bones['ik']['ctrl']['terminal'] = [] bpy.ops.object.mode_set(mode='EDIT') @@ -521,6 +525,26 @@ class Rig: eb[ ctrl ].parent = None eb[ ctrl ].use_connect = False + # MCH for ik control + ctrl_socket = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_socket')) + eb[ctrl_socket].tail = eb[ctrl_socket].head + 0.8*(eb[ctrl_socket].tail-eb[ctrl_socket].head) + eb[ctrl_socket].parent = None + eb[ctrl].parent = eb[ctrl_socket] + + ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) + eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) + eb[ctrl_root].use_connect = False + eb[ctrl_root].parent = eb['root'] + + if eb[org_bones[0]].parent: + paw_parent = eb[org_bones[0]].parent + ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) + eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) + eb[ctrl_parent].use_connect = False + eb[ctrl_parent].parent = eb[org_bones[0]].parent + else: + paw_parent = None + # Create heel control bone heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) heel = copy_bone( self.obj, org_bones[2], heel ) @@ -544,9 +568,22 @@ class Rig: eb[ ctrl ].length = l # Set up constraints - # Constrain mch target bone to the ik control and mch stretch + # Constrain ik ctrl to root / parent + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_root, + }) + + if paw_parent: + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_parent, + 'influence' : 0.0, + }) + + # Constrain mch target bone to the ik control and mch stretch make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', 'subtarget' : bones['ik']['mch_str'], @@ -680,42 +717,136 @@ class Rig: bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] + if paw_parent: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + else: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] + return bones - # def create_terminal( self, limb_type, bones ): - # if limb_type == 'arm': - # return create_arm( self, bones ) - # elif limb_type == 'leg': - # return create_leg( self, bones ) - # elif limb_type == 'paw': - # return create_paw( self, bones ) + def create_drivers(self, bones): + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + ctrl = pb[bones['ik']['mch_foot'][0]] + + props = [ "IK_follow", "root/parent" ] + + for prop in props: + if prop == 'IK_follow': + + ctrl[prop] = True + rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + rna_prop["min"] = False + rna_prop["max"] = True + rna_prop["description"] = prop + + drv = ctrl.constraints[ 0 ].driver_add("mute").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 = \ + ctrl.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 + + if len(ctrl.constraints) > 1: + drv = ctrl.constraints[ 1 ].driver_add("mute").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 = \ + ctrl.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 + + elif len(ctrl.constraints) > 1: + ctrl[prop]=0.0 + rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + # drv = ctrl.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 = \ + # ctrl.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 + + drv = ctrl.constraints[ 1 ].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 = \ + ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' def generate( self ): - bpy.ops.object.mode_set(mode ='EDIT') - eb = self.obj.data.edit_bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Clear parents for org bones + for bone in self.org_bones[1:]: + eb[bone].use_connect = False + eb[bone].parent = None + + bones = {} - # Clear parents for org bones - for bone in self.org_bones[1:]: - eb[bone].use_connect = False - eb[bone].parent = None + # Create mch limb parent + bones['parent'] = self.create_parent() + bones['tweak'] = self.create_tweak() + bones['def'] = self.create_def( bones['tweak']['ctrl'] ) + bones['ik'] = self.create_ik( bones['parent'] ) + bones['fk'] = self.create_fk( bones['parent'] ) + + self.org_parenting_and_switch( + self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] + ) - bones = {} + bones = self.create_paw( bones ) + self.create_drivers( bones ) - # Create mch limb parent - bones['parent'] = self.create_parent() - bones['tweak'] = self.create_tweak() - bones['def'] = self.create_def( bones['tweak']['ctrl'] ) - bones['ik'] = self.create_ik( bones['parent'] ) - bones['fk'] = self.create_fk( bones['parent'] ) + controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] - self.org_parenting_and_switch( - self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] - ) + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) - bones = self.create_paw( bones ) + script = create_script( bones, 'paw' ) + script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') - return [ create_script( bones, 'paw' ) ] + return [ script ] def add_parameters( params ): diff --git a/rigify/rigs/pitchipoy/limbs/super_leg.py b/rigify/rigs/pitchipoy/limbs/super_leg.py index 2bc206a9..06df1c74 100644 --- a/rigify/rigs/pitchipoy/limbs/super_leg.py +++ b/rigify/rigs/pitchipoy/limbs/super_leg.py @@ -22,7 +22,8 @@ ctrl = '%s' if is_selected( controls ): layout.prop( pose_bones[ ctrl ], '["%s"]') - layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) + if '%s' in pose_bones[ctrl].keys(): + layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) """ class Rig: @@ -105,7 +106,6 @@ class Rig: return mch - def create_tweak( self ): org_bones = self.org_bones @@ -231,7 +231,6 @@ class Rig: return tweaks - def create_def( self, tweaks ): org_bones = self.org_bones @@ -338,7 +337,6 @@ class Rig: return def_bones - def create_ik( self, parent ): org_bones = self.org_bones @@ -396,7 +394,6 @@ class Rig: 'mch_str' : mch_str } - def create_fk( self, parent ): org_bones = self.org_bones.copy() @@ -446,7 +443,6 @@ class Rig: return { 'ctrl' : ctrls, 'mch' : mch } - def org_parenting_and_switch( self, org, ik, fk, parent ): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones @@ -495,7 +491,6 @@ class Rig: var.targets[0].data_path = \ pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - def create_leg( self, bones ): org_bones = list( [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) @@ -535,10 +530,14 @@ class Rig: eb[ctrl_root].use_connect = False eb[ctrl_root].parent = eb['root'] - ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) - eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) - eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent + if eb[org_bones[0]].parent: + leg_parent = eb[org_bones[0]].parent + ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) + eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) + eb[ctrl_parent].use_connect = False + eb[ctrl_parent].parent = eb[org_bones[0]].parent + else: + leg_parent = None # Create heel ctrl bone heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) @@ -616,10 +615,6 @@ class Rig: eb[ rock1_mch ].parent = eb[ rock2_mch ] eb[ rock2_mch ].parent = eb[ ctrl ] - # Get target for ctrl constraints - # Todo this should be better : target = strip_org(eb[org_bones[0]].parent.name) - #target = eb[org_bones[0]].parent.name - # Constrain rock and roll MCH bones make_constraint( self, roll1_mch, { 'constraint' : 'COPY_ROTATION', @@ -699,20 +694,12 @@ class Rig: 'subtarget' : ctrl_root, }) - - make_constraint( self, ctrl_socket, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : ctrl_parent, - 'influence' : 0.0, - }) - - - # pbone = self.obj.pose.bones[target] - # - # const = self.obj.pose.bones[ctrl].constraints[1] - # const.inverse_matrix = (self.obj.matrix_world*pbone.matrix).inverted() - - # Constrain mch target bone to the ik control and mch stretch + if leg_parent: + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_parent, + 'influence' : 0.0, + }) make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', @@ -841,19 +828,13 @@ class Rig: bones['ik']['ctrl']['terminal'] += [ toes ] bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + if leg_parent: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + else: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] return bones - # def create_terminal( self, limb_type, bones ): - # if limb_type == 'arm': - # return create_arm( self, bones ) - # elif limb_type == 'leg': - # return create_leg( self, bones ) - # elif limb_type == 'paw': - # return create_paw( self, bones ) - - def create_drivers(self, bones): bpy.ops.object.mode_set(mode ='OBJECT') @@ -866,7 +847,7 @@ class Rig: for prop in props: if prop == 'IK_follow': - ctrl[prop]=True + ctrl[prop] = True rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) rna_prop["min"] = False rna_prop["max"] = True @@ -889,24 +870,25 @@ class Rig: drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 - drv = ctrl.constraints[ 1 ].driver_add("mute").driver - drv.type = 'AVERAGE' + if len(ctrl.constraints) > 1: + drv = ctrl.constraints[ 1 ].driver_add("mute").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 = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + 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 + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 - else: + elif len(ctrl.constraints) > 1: ctrl[prop]=0.0 rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) rna_prop["min"] = 0.0 @@ -915,22 +897,22 @@ class Rig: rna_prop["soft_max"] = 1.0 rna_prop["description"] = prop - drv = ctrl.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 = \ - ctrl.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 + # drv = ctrl.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 = \ + # ctrl.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 drv = ctrl.constraints[ 1 ].driver_add("influence").driver drv.type = 'AVERAGE' @@ -942,59 +924,47 @@ class Rig: var.targets[0].data_path = \ ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + def generate(self): + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones - def generate( self ): - bpy.ops.object.mode_set(mode ='EDIT') - eb = self.obj.data.edit_bones - - # Clear parents for org bones - for bone in self.org_bones[1:]: - eb[bone].use_connect = False - eb[bone].parent = None + # Clear parents for org bones + for bone in self.org_bones[1:]: + eb[bone].use_connect = False + eb[bone].parent = None - bones = {} + bones = {} - # Create mch limb parent - bones['parent'] = self.create_parent() - bones['tweak'] = self.create_tweak() - bones['def'] = self.create_def( bones['tweak']['ctrl'] ) - bones['ik'] = self.create_ik( bones['parent'] ) - bones['fk'] = self.create_fk( bones['parent'] ) + # Create mch limb parent + bones['parent'] = self.create_parent() + bones['tweak'] = self.create_tweak() + bones['def'] = self.create_def( bones['tweak']['ctrl'] ) + bones['ik'] = self.create_ik( bones['parent'] ) + bones['fk'] = self.create_fk( bones['parent'] ) - self.org_parenting_and_switch( - self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] - ) + self.org_parenting_and_switch( + self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] + ) - bones = self.create_leg( bones ) - self.create_drivers( bones ) + bones = self.create_leg( bones ) + self.create_drivers( bones ) - controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] + controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] - # Create UI - controls_string = ", ".join(["'" + x + "'" for x in controls]) + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) - script = create_script( bones, 'leg' ) - script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent') + script = create_script( bones, 'leg' ) + script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') - return [ script ] + return [ script ] -def add_parameters( params ): +def add_parameters(params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ - # items = [ - # ('arm', 'Arm', ''), - # ('leg', 'Leg', ''), - # ('paw', 'Paw', '') - # ] - # params.limb_type = bpy.props.EnumProperty( - # items = items, - # name = "Limb Type", - # default = 'leg' - # ) - items = [ ('x', 'X', ''), ('y', 'Y', ''), diff --git a/rigify/rigs/pitchipoy/limbs/super_rear_paw.py b/rigify/rigs/pitchipoy/limbs/super_rear_paw.py index f84b618d..c31346c9 100644 --- a/rigify/rigs/pitchipoy/limbs/super_rear_paw.py +++ b/rigify/rigs/pitchipoy/limbs/super_rear_paw.py @@ -12,6 +12,18 @@ from ..super_widgets import create_ikarrow_widget from ..super_widgets import create_foot_widget, create_ballsocket_widget from math import trunc + +extra_script = """ +controls = [%s] +ctrl = '%s' + +if is_selected( controls ): + layout.prop( pose_bones[ ctrl ], '["%s"]') + if '%s' in pose_bones[ctrl].keys(): + layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) +""" + + class Rig: def __init__(self, obj, bone_name, params): """ Initialize torso rig and key rig properties """ @@ -230,7 +242,6 @@ class Rig: return tweaks - def create_def( self, tweaks ): org_bones = self.org_bones @@ -337,7 +348,6 @@ class Rig: return def_bones - def create_ik( self, parent ): org_bones = self.org_bones @@ -395,7 +405,6 @@ class Rig: 'mch_str' : mch_str } - def create_fk( self, parent ): org_bones = self.org_bones.copy() @@ -447,7 +456,6 @@ class Rig: return { 'ctrl' : ctrls, 'mch' : mch } - def org_parenting_and_switch( self, org, ik, fk, parent ): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones @@ -496,13 +504,12 @@ class Rig: var.targets[0].data_path = \ pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - def create_paw( self, bones ): + org_bones = list( [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) ) - bones['ik']['ctrl']['terminal'] = [] bpy.ops.object.mode_set(mode='EDIT') @@ -516,6 +523,26 @@ class Rig: eb[ ctrl ].parent = None eb[ ctrl ].use_connect = False + # MCH for ik control + ctrl_socket = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_socket')) + eb[ctrl_socket].tail = eb[ctrl_socket].head + 0.8*(eb[ctrl_socket].tail-eb[ctrl_socket].head) + eb[ctrl_socket].parent = None + eb[ctrl].parent = eb[ctrl_socket] + + ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) + eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) + eb[ctrl_root].use_connect = False + eb[ctrl_root].parent = eb['root'] + + if eb[org_bones[0]].parent: + paw_parent = eb[org_bones[0]].parent + ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) + eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) + eb[ctrl_parent].use_connect = False + eb[ctrl_parent].parent = eb[org_bones[0]].parent + else: + paw_parent = None + # Create heel control bone heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) heel = copy_bone( self.obj, org_bones[2], heel ) @@ -539,9 +566,22 @@ class Rig: eb[ ctrl ].length = l # Set up constraints - # Constrain mch target bone to the ik control and mch stretch + # Constrain ik ctrl to root / parent + + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_root, + }) + + if paw_parent: + make_constraint( self, ctrl_socket, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : ctrl_parent, + 'influence' : 0.0, + }) + # Constrain mch target bone to the ik control and mch stretch make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', 'subtarget' : bones['ik']['mch_str'], @@ -675,18 +715,103 @@ class Rig: bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] + if paw_parent: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + else: + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] + return bones - # def create_terminal( self, limb_type, bones ): - # if limb_type == 'arm': - # return create_arm( self, bones ) - # elif limb_type == 'leg': - # return create_leg( self, bones ) - # elif limb_type == 'paw': - # return create_paw( self, bones ) + def create_drivers(self, bones): + + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + ctrl = pb[bones['ik']['mch_foot'][0]] + + props = [ "IK_follow", "root/parent" ] + for prop in props: + if prop == 'IK_follow': - def generate( self ): + ctrl[prop] = True + rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + rna_prop["min"] = False + rna_prop["max"] = True + rna_prop["description"] = prop + + drv = ctrl.constraints[ 0 ].driver_add("mute").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 = \ + ctrl.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 + + if len(ctrl.constraints) > 1: + drv = ctrl.constraints[ 1 ].driver_add("mute").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 = \ + ctrl.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 + + elif len(ctrl.constraints) > 1: + ctrl[prop]=0.0 + rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + # drv = ctrl.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 = \ + # ctrl.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 + + drv = ctrl.constraints[ 1 ].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 = \ + ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + + def generate(self): bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones @@ -709,8 +834,17 @@ class Rig: ) bones = self.create_paw( bones ) + self.create_drivers( bones ) + + controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] + + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) + + script = create_script( bones, 'paw' ) + script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') - return [ create_script( bones, 'paw' ) ] + return [ script ] def add_parameters( params ): -- cgit v1.2.3