From f36789d8bc728bc7ec3c9738f1ca76e8f017ce7a Mon Sep 17 00:00:00 2001 From: Lucio Rossi Date: Sun, 14 May 2017 18:30:06 +0200 Subject: Rigify 0.5 with legacy mode --- rigify/legacy/rigs/pitchipoy/__init__.py | 0 rigify/legacy/rigs/pitchipoy/limbs/__init__.py | 0 rigify/legacy/rigs/pitchipoy/limbs/arm.py | 116 + rigify/legacy/rigs/pitchipoy/limbs/leg.py | 333 +++ rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py | 70 + rigify/legacy/rigs/pitchipoy/limbs/paw.py | 214 ++ rigify/legacy/rigs/pitchipoy/limbs/super_limb.py | 785 +++++++ rigify/legacy/rigs/pitchipoy/limbs/ui.py | 143 ++ rigify/legacy/rigs/pitchipoy/simple_tentacle.py | 350 +++ rigify/legacy/rigs/pitchipoy/super_copy.py | 159 ++ rigify/legacy/rigs/pitchipoy/super_face.py | 2400 +++++++++++++++++++++ rigify/legacy/rigs/pitchipoy/super_finger.py | 414 ++++ rigify/legacy/rigs/pitchipoy/super_palm.py | 324 +++ rigify/legacy/rigs/pitchipoy/super_torso_turbo.py | 911 ++++++++ rigify/legacy/rigs/pitchipoy/super_widgets.py | 164 ++ rigify/legacy/rigs/pitchipoy/tentacle.py | 509 +++++ 16 files changed, 6892 insertions(+) create mode 100644 rigify/legacy/rigs/pitchipoy/__init__.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/__init__.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/arm.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/leg.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/paw.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/super_limb.py create mode 100644 rigify/legacy/rigs/pitchipoy/limbs/ui.py create mode 100644 rigify/legacy/rigs/pitchipoy/simple_tentacle.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_copy.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_face.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_finger.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_palm.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_torso_turbo.py create mode 100644 rigify/legacy/rigs/pitchipoy/super_widgets.py create mode 100644 rigify/legacy/rigs/pitchipoy/tentacle.py (limited to 'rigify/legacy/rigs/pitchipoy') diff --git a/rigify/legacy/rigs/pitchipoy/__init__.py b/rigify/legacy/rigs/pitchipoy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rigify/legacy/rigs/pitchipoy/limbs/__init__.py b/rigify/legacy/rigs/pitchipoy/limbs/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/rigify/legacy/rigs/pitchipoy/limbs/arm.py b/rigify/legacy/rigs/pitchipoy/limbs/arm.py new file mode 100644 index 00000000..43327ec8 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/arm.py @@ -0,0 +1,116 @@ +#====================== 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 bpy +from ....utils import MetarigError +from ....utils import create_widget, copy_bone +from ....utils import strip_org +from .limb_utils import * +from ..super_widgets import create_hand_widget +from rna_prop_ui import rna_idprop_ui_prop_get + +def create_arm( cls, bones ): + org_bones = cls.org_bones + + bpy.ops.object.mode_set(mode='EDIT') + eb = cls.obj.data.edit_bones + + ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) + + # Create IK arm control + ctrl = copy_bone( cls.obj, org_bones[2], ctrl ) + + # clear parent (so that rigify will parent to root) + eb[ ctrl ].parent = None + eb[ ctrl ].use_connect = False + + # Parent + eb[ bones['ik']['mch_target'] ].parent = eb[ ctrl ] + eb[ bones['ik']['mch_target'] ].use_connect = False + + # Set up constraints + # Constrain mch target bone to the ik control and mch stretch + + make_constraint( cls, bones['ik']['mch_target'], { + 'constraint' : 'COPY_LOCATION', + 'subtarget' : bones['ik']['mch_str'], + 'head_tail' : 1.0 + }) + + # Constrain mch ik stretch bone to the ik control + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : ctrl, + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : ctrl, + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'LIMIT_SCALE', + 'use_min_y' : True, + 'use_max_y' : True, + 'max_y' : 1.05, + 'owner_space' : 'LOCAL' + }) + + pb = cls.obj.pose.bones + + # Modify rotation mode for ik and tweak controls + pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY' + + for b in bones['tweak']['ctrl']: + pb[b].rotation_mode = 'ZXY' + + # Create ik/fk switch property + pb_parent = pb[ bones['parent'] ] + + pb_parent['IK_Strertch'] = 1.0 + prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = 'IK Stretch' + + # Add driver to limit scale constraint influence + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver + drv.type = 'SUM' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = cls.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + drv_modifier = cls.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 + + # Create hand widget + create_hand_widget(cls.obj, ctrl, bone_transform_name=None) + + bones['ik']['ctrl']['terminal'] = [ ctrl ] + + return bones diff --git a/rigify/legacy/rigs/pitchipoy/limbs/leg.py b/rigify/legacy/rigs/pitchipoy/limbs/leg.py new file mode 100644 index 00000000..9176bd92 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/leg.py @@ -0,0 +1,333 @@ +#====================== 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 bpy, math +from ....utils import MetarigError, connected_children_names +from ....utils import create_widget, copy_bone, create_circle_widget +from ....utils import strip_org, flip_bone, put_bone +from rna_prop_ui import rna_idprop_ui_prop_get +from ..super_widgets import create_foot_widget, create_ballsocket_widget +from .limb_utils import * + +def create_leg( cls, bones ): + org_bones = list( + [cls.org_bones[0]] + connected_children_names(cls.obj, cls.org_bones[0]) + ) + + bones['ik']['ctrl']['terminal'] = [] + + bpy.ops.object.mode_set(mode='EDIT') + eb = cls.obj.data.edit_bones + + # Create toes def bone + toes_def = get_bone_name( org_bones[-1], 'def' ) + toes_def = copy_bone( cls.obj, org_bones[-1], toes_def ) + + eb[ toes_def ].use_connect = False + eb[ toes_def ].parent = eb[ bones['def'][-1] ] + eb[ toes_def ].use_connect = True + + bones['def'] += [ toes_def ] + + # Create IK leg control + ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) + ctrl = copy_bone( cls.obj, org_bones[2], ctrl ) + + # clear parent (so that rigify will parent to root) + eb[ ctrl ].parent = None + eb[ ctrl ].use_connect = False + + # Create heel ctrl bone + heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) + heel = copy_bone( cls.obj, org_bones[2], heel ) + orient_bone( cls, eb[ heel ], 'y', 0.5 ) + eb[ heel ].length = eb[ org_bones[2] ].length / 2 + + # Reset control position and orientation + l = eb[ ctrl ].length + orient_bone( cls, eb[ ctrl ], 'y', reverse = True ) + eb[ ctrl ].length = l + + # Parent + eb[ heel ].use_connect = False + eb[ heel ].parent = eb[ ctrl ] + + eb[ bones['ik']['mch_target'] ].parent = eb[ heel ] + eb[ bones['ik']['mch_target'] ].use_connect = False + + # Create foot mch rock and roll bones + + # Get the tmp heel (floating unconnected without children) + tmp_heel = "" + for b in cls.obj.data.bones[ org_bones[2] ].children: + if not b.use_connect and not b.children: + tmp_heel = b.name + + # roll1 MCH bone + roll1_mch = get_bone_name( tmp_heel, 'mch', 'roll' ) + roll1_mch = copy_bone( cls.obj, org_bones[2], roll1_mch ) + + # clear parent + eb[ roll1_mch ].use_connect = False + eb[ roll1_mch ].parent = None + + flip_bone( cls.obj, roll1_mch ) + + # Create 2nd roll mch, and two rock mch bones + roll2_mch = get_bone_name( tmp_heel, 'mch', 'roll' ) + roll2_mch = copy_bone( cls.obj, org_bones[3], roll2_mch ) + + eb[ roll2_mch ].use_connect = False + eb[ roll2_mch ].parent = None + + put_bone( + cls.obj, + roll2_mch, + ( eb[ tmp_heel ].head + eb[ tmp_heel ].tail ) / 2 + ) + + eb[ roll2_mch ].length /= 4 + + # Rock MCH bones + rock1_mch = get_bone_name( tmp_heel, 'mch', 'rock' ) + rock1_mch = copy_bone( cls.obj, tmp_heel, rock1_mch ) + + eb[ rock1_mch ].use_connect = False + eb[ rock1_mch ].parent = None + + orient_bone( cls, eb[ rock1_mch ], 'y', 1.0, reverse = True ) + eb[ rock1_mch ].length = eb[ tmp_heel ].length / 2 + + rock2_mch = get_bone_name( tmp_heel, 'mch', 'rock' ) + rock2_mch = copy_bone( cls.obj, tmp_heel, rock2_mch ) + + eb[ rock2_mch ].use_connect = False + eb[ rock2_mch ].parent = None + + orient_bone( cls, eb[ rock2_mch ], 'y', 1.0 ) + eb[ rock2_mch ].length = eb[ tmp_heel ].length / 2 + + # Parent rock and roll MCH bones + eb[ roll1_mch ].parent = eb[ roll2_mch ] + eb[ roll2_mch ].parent = eb[ rock1_mch ] + eb[ rock1_mch ].parent = eb[ rock2_mch ] + eb[ rock2_mch ].parent = eb[ ctrl ] + + # Constrain rock and roll MCH bones + make_constraint( cls, roll1_mch, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : heel, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + }) + make_constraint( cls, roll1_mch, { + 'constraint' : 'LIMIT_ROTATION', + 'use_limit_x' : True, + 'max_x' : math.radians(360), + 'owner_space' : 'LOCAL' + }) + make_constraint( cls, roll2_mch, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : heel, + 'use_y' : False, + 'use_z' : False, + 'invert_x' : True, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + }) + make_constraint( cls, roll2_mch, { + 'constraint' : 'LIMIT_ROTATION', + 'use_limit_x' : True, + 'max_x' : math.radians(360), + 'owner_space' : 'LOCAL' + }) + + pb = cls.obj.pose.bones + for i,b in enumerate([ rock1_mch, rock2_mch ]): + head_tail = pb[b].head - pb[tmp_heel].head + if '.L' in b: + if not i: + min_y = 0 + max_y = math.radians(360) + else: + min_y = math.radians(-360) + max_y = 0 + else: + if not i: + min_y = math.radians(-360) + max_y = 0 + else: + min_y = 0 + max_y = math.radians(360) + + + make_constraint( cls, b, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : heel, + 'use_x' : False, + 'use_z' : False, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + }) + make_constraint( cls, b, { + 'constraint' : 'LIMIT_ROTATION', + 'use_limit_y' : True, + 'min_y' : min_y, + 'max_y' : max_y, + 'owner_space' : 'LOCAL' + }) + + # Constrain 4th ORG to roll2 MCH bone + make_constraint( cls, org_bones[3], { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : roll2_mch + }) + + # Set up constraints + # Constrain mch target bone to the ik control and mch stretch + + make_constraint( cls, bones['ik']['mch_target'], { + 'constraint' : 'COPY_LOCATION', + 'subtarget' : bones['ik']['mch_str'], + 'head_tail' : 1.0 + }) + + # Constrain mch ik stretch bone to the ik control + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : roll1_mch, + 'head_tail' : 1.0 + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : roll1_mch, + 'head_tail' : 1.0 + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'LIMIT_SCALE', + 'use_min_y' : True, + 'use_max_y' : True, + 'max_y' : 1.05, + 'owner_space' : 'LOCAL' + }) + + # Modify rotation mode for ik and tweak controls + pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY' + + for b in bones['tweak']['ctrl']: + pb[b].rotation_mode = 'ZXY' + + # Create ik/fk switch property + pb_parent = pb[ bones['parent'] ] + + pb_parent['IK_Strertch'] = 1.0 + prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = 'IK Stretch' + + # Add driver to limit scale constraint influence + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = cls.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + drv_modifier = cls.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 + + # Create leg widget + create_foot_widget(cls.obj, ctrl, bone_transform_name=None) + + # Create heel ctrl locks + pb[ heel ].lock_location = True, True, True + pb[ heel ].lock_rotation = False, False, True + pb[ heel ].lock_scale = True, True, True + + # Add ballsocket widget to heel + create_ballsocket_widget(cls.obj, heel, bone_transform_name=None) + + bpy.ops.object.mode_set(mode='EDIT') + eb = cls.obj.data.edit_bones + + if len( org_bones ) >= 4: + # Create toes control bone + toes = get_bone_name( org_bones[3], 'ctrl' ) + toes = copy_bone( cls.obj, org_bones[3], toes ) + + eb[ toes ].use_connect = False + eb[ toes ].parent = eb[ org_bones[3] ] + + # Constrain toes def bones + make_constraint( cls, bones['def'][-2], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : toes + }) + make_constraint( cls, bones['def'][-2], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : toes + }) + + make_constraint( cls, bones['def'][-1], { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : toes + }) + + # Find IK/FK switch property + pb = cls.obj.pose.bones + prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' ) + + # Add driver to limit scale constraint influence + b = org_bones[3] + drv = pb[b].constraints[-1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = cls.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + drv_modifier = cls.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 + + # Create toe circle widget + create_circle_widget(cls.obj, toes, radius=0.4, head_tail=0.5) + + bones['ik']['ctrl']['terminal'] += [ toes ] + + bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] + + return bones diff --git a/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py new file mode 100644 index 00000000..73e4f472 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py @@ -0,0 +1,70 @@ +import bpy, re +from mathutils import Vector +from ....utils import org, strip_org, make_mechanism_name, make_deformer_name +from ....utils import MetarigError + +bilateral_suffixes = ['.L','.R'] + +def orient_bone( cls, eb, axis, scale = 1.0, reverse = False ): + v = Vector((0,0,0)) + + setattr(v,axis,scale) + + if reverse: + tail_vec = v * cls.obj.matrix_world + eb.head[:] = eb.tail + eb.tail[:] = eb.head + tail_vec + else: + tail_vec = v * cls.obj.matrix_world + eb.tail[:] = eb.head + tail_vec + + eb.roll = 0.0 + +def make_constraint( cls, bone, constraint ): + bpy.ops.object.mode_set(mode = 'OBJECT') + pb = cls.obj.pose.bones + + owner_pb = pb[bone] + const = owner_pb.constraints.new( constraint['constraint'] ) + + constraint['target'] = cls.obj + + # filter contraint props to those that actually exist in the currnet + # type of constraint, then assign values to each + for p in [ k for k in constraint.keys() if k in dir(const) ]: + if p in dir( const ): + setattr( const, p, constraint[p] ) + else: + raise MetarigError( + "RIGIFY ERROR: property %s does not exist in %s constraint" % ( + p, constraint['constraint'] + )) + +def get_bone_name( name, btype, suffix = '' ): + # RE pattern match right or left parts + # match the letter "L" (or "R"), followed by an optional dot (".") + # and 0 or more digits at the end of the the string + pattern = r'^(\S+)(\.\S+)$' + + name = strip_org( name ) + + types = { + 'mch' : make_mechanism_name( name ), + 'org' : org( name ), + 'def' : make_deformer_name( name ), + 'ctrl' : name + } + + name = types[btype] + + if suffix: + results = re.match( pattern, name ) + bname, addition = ('','') + + if results: + bname, addition = results.groups() + name = bname + "_" + suffix + addition + else: + name = name + "_" + suffix + + return name diff --git a/rigify/legacy/rigs/pitchipoy/limbs/paw.py b/rigify/legacy/rigs/pitchipoy/limbs/paw.py new file mode 100644 index 00000000..89de5e90 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/paw.py @@ -0,0 +1,214 @@ +#====================== 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 bpy +from ....utils import MetarigError, connected_children_names +from ....utils import create_widget, copy_bone, create_circle_widget +from ....utils import strip_org, flip_bone +from rna_prop_ui import rna_idprop_ui_prop_get +from ..super_widgets import create_foot_widget, create_ballsocket_widget +from .limb_utils import * + +def create_paw( cls, bones ): + org_bones = list( + [cls.org_bones[0]] + connected_children_names(cls.obj, cls.org_bones[0]) + ) + + + bones['ik']['ctrl']['terminal'] = [] + + bpy.ops.object.mode_set(mode='EDIT') + eb = cls.obj.data.edit_bones + + # Create IK paw control + ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) + ctrl = copy_bone( cls.obj, org_bones[2], ctrl ) + + # clear parent (so that rigify will parent to root) + eb[ ctrl ].parent = None + eb[ ctrl ].use_connect = False + + # Create heel control bone + heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) + heel = copy_bone( cls.obj, org_bones[2], heel ) + + # clear parent + eb[ heel ].parent = None + eb[ heel ].use_connect = False + + # Parent + eb[ heel ].parent = eb[ ctrl ] + eb[ heel ].use_connect = False + + flip_bone( cls.obj, heel ) + + eb[ bones['ik']['mch_target'] ].parent = eb[ heel ] + eb[ bones['ik']['mch_target'] ].use_connect = False + + # Reset control position and orientation + l = eb[ ctrl ].length + orient_bone( cls, eb[ ctrl ], 'y', reverse = True ) + eb[ ctrl ].length = l + + # Set up constraints + # Constrain mch target bone to the ik control and mch stretch + + make_constraint( cls, bones['ik']['mch_target'], { + 'constraint' : 'COPY_LOCATION', + 'subtarget' : bones['ik']['mch_str'], + 'head_tail' : 1.0 + }) + + # Constrain mch ik stretch bone to the ik control + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : heel, + 'head_tail' : 1.0 + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : heel, + 'head_tail' : 1.0 + }) + make_constraint( cls, bones['ik']['mch_str'], { + 'constraint' : 'LIMIT_SCALE', + 'use_min_y' : True, + 'use_max_y' : True, + 'max_y' : 1.05, + 'owner_space' : 'LOCAL' + }) + + pb = cls.obj.pose.bones + + # Modify rotation mode for ik and tweak controls + pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY' + + for b in bones['tweak']['ctrl']: + pb[b].rotation_mode = 'ZXY' + + # Create ik/fk switch property + pb_parent = pb[ bones['parent'] ] + + pb_parent['IK_Strertch'] = 1.0 + prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = 'IK Stretch' + + # Add driver to limit scale constraint influence + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = cls.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + drv_modifier = cls.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 + + # Create paw widget + create_foot_widget(cls.obj, ctrl, bone_transform_name=None) + + # Create heel ctrl locks + pb[ heel ].lock_location = True, True, True + + # Add ballsocket widget to heel + create_ballsocket_widget(cls.obj, heel, bone_transform_name=None) + + bpy.ops.object.mode_set(mode='EDIT') + eb = cls.obj.data.edit_bones + + if len( org_bones ) >= 4: + # Create toes control bone + toes = get_bone_name( org_bones[3], 'ctrl' ) + toes = copy_bone( cls.obj, org_bones[3], toes ) + + eb[ toes ].use_connect = False + eb[ toes ].parent = eb[ org_bones[3] ] + + # Create toes mch bone + toes_mch = get_bone_name( org_bones[3], 'mch' ) + toes_mch = copy_bone( cls.obj, org_bones[3], toes_mch ) + + eb[ toes_mch ].use_connect = False + eb[ toes_mch ].parent = eb[ ctrl ] + + eb[ toes_mch ].length /= 4 + + # Constrain 4th ORG to toes MCH bone + make_constraint( cls, org_bones[3], { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : toes_mch + }) + + # Constrain toes def bones + + make_constraint( cls, bones['def'][-1], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : toes, + 'head_tail' : 1 + }) + make_constraint( cls, bones['def'][-1], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : toes, + 'head_tail' : 1 + }) + + + # Find IK/FK switch property + pb = cls.obj.pose.bones + prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' ) + + # Add driver to limit scale constraint influence + b = org_bones[3] + drv = pb[b].constraints[-1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = cls.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + drv_modifier = cls.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 + + # Create toe circle widget + create_circle_widget(cls.obj, toes, radius=0.4, head_tail=0.5) + + bones['ik']['ctrl']['terminal'] += [ toes ] + + bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] + + return bones diff --git a/rigify/legacy/rigs/pitchipoy/limbs/super_limb.py b/rigify/legacy/rigs/pitchipoy/limbs/super_limb.py new file mode 100644 index 00000000..91efdb48 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/super_limb.py @@ -0,0 +1,785 @@ +import bpy, re +from .arm import create_arm +from .leg import create_leg +from .paw import create_paw +from .ui import create_script +from .limb_utils import * +from mathutils import Vector +from ....utils import copy_bone, flip_bone, put_bone, create_cube_widget +from ....utils import strip_org, make_deformer_name, create_widget +from ....utils import create_circle_widget, create_sphere_widget +from ....utils import MetarigError, make_mechanism_name, org +from ....utils import create_limb_widget, connected_children_names +from rna_prop_ui import rna_idprop_ui_prop_get +from ..super_widgets import create_ikarrow_widget +from math import trunc + + +class Rig: + + def __init__(self, obj, bone_name, params): + """ Initialize super_limb rig and key rig properties """ + self.obj = obj + self.params = params + + if params.limb_type != 'paw': + self.org_bones = list( + [bone_name] + connected_children_names(obj, bone_name) + )[:3] # The basic limb is the first 3 bones + else: + self.org_bones = list( + [bone_name] + connected_children_names(obj, bone_name) + )[:4] # The basic limb is the first 4 bones for a paw + + self.segments = params.segments + self.bbones = params.bbones + self.limb_type = params.limb_type + self.rot_axis = params.rotation_axis + + # Assign values to tweak/FK layers props if opted by user + if params.tweak_extra_layers: + self.tweak_layers = list(params.tweak_layers) + else: + self.tweak_layers = None + + if params.fk_extra_layers: + self.fk_layers = list(params.fk_layers) + else: + self.fk_layers = None + + def create_parent(self): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + name = get_bone_name( strip_org( org_bones[0] ), 'mch', 'parent' ) + + mch = copy_bone( self.obj, org_bones[0], name ) + orient_bone( self, eb[mch], 'y' ) + eb[ mch ].length = eb[ org_bones[0] ].length / 4 + + eb[ mch ].parent = eb[ org_bones[0] ].parent + + eb[ mch ].roll = 0.0 + + # Constraints + make_constraint( self, mch, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : 'root' + }) + + make_constraint( self, mch, { + 'constraint' : 'COPY_SCALE', + 'subtarget' : 'root' + }) + + # Limb Follow Driver + pb = self.obj.pose.bones + + name = 'FK_limb_follow' + + pb[ mch ][ name ] = 0.0 + prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = name + + drv = pb[ mch ].constraints[ 0 ].driver_add("influence").driver + + drv.type = 'AVERAGE' + var = drv.variables.new() + var.name = name + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = pb[ mch ].path_from_id() + \ + '[' + '"' + name + '"' + ']' + + return mch + + def create_tweak( self ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + tweaks = {} + tweaks['ctrl'] = [] + tweaks['mch' ] = [] + + # Create and parent mch and ctrl tweaks + for i,org in enumerate(org_bones): + if i < len(org_bones) - 1: + # Create segments if specified + for j in range( self.segments ): + # MCH + name = get_bone_name( strip_org(org), 'mch', 'tweak' ) + mch = copy_bone( self.obj, org, name ) + + # CTRL + name = get_bone_name( strip_org(org), 'ctrl', 'tweak' ) + ctrl = copy_bone( self.obj, org, name ) + + eb[ mch ].length /= self.segments + eb[ ctrl ].length /= self.segments + + # If we have more than one segments, place the head of the + # 2nd and onwards at the correct position + if j > 0: + put_bone(self.obj, mch, eb[ tweaks['mch' ][-1] ].tail) + put_bone(self.obj, ctrl, eb[ tweaks['ctrl'][-1] ].tail) + + tweaks['ctrl'] += [ ctrl ] + tweaks['mch' ] += [ mch ] + + # Parenting the tweak ctrls to mchs + eb[ mch ].parent = eb[ org ] + eb[ ctrl ].parent = eb[ mch ] + + else: # Last limb bone - is not subdivided + name = get_bone_name( strip_org(org), 'mch', 'tweak' ) + mch = copy_bone( self.obj, org_bones[i-1], name ) + eb[ mch ].length = eb[org].length / 4 + put_bone( + self.obj, + mch, + eb[org_bones[i-1]].tail + ) + + ctrl = get_bone_name( strip_org(org), 'ctrl', 'tweak' ) + ctrl = copy_bone( self.obj, org, ctrl ) + eb[ ctrl ].length = eb[org].length / 2 + + tweaks['mch'] += [ mch ] + tweaks['ctrl'] += [ ctrl ] + + # Parenting the tweak ctrls to mchs + eb[ mch ].parent = eb[ org ] + eb[ ctrl ].parent = eb[ mch ] + + # Scale to reduce widget size and maintain conventions! + for mch, ctrl in zip( tweaks['mch'], tweaks['ctrl'] ): + eb[ mch ].length /= 4 + eb[ ctrl ].length /= 2 + + # Contraints + if self.limb_type == 'paw': + + for i,b in enumerate( tweaks['mch'] ): + first = 0 + middle = trunc( len( tweaks['mch'] ) / 3 ) + middle1 = middle + self.segments + last = len( tweaks['mch'] ) - 1 + + if i == first or i == middle or i == middle1: + make_constraint( self, b, { + 'constraint' : 'COPY_SCALE', + 'subtarget' : 'root' + }) + elif i != last: + targets = [] + factor = 0 + if i < middle: + dt_target_idx = middle + targets = [first,middle] + elif i > middle and i < middle1: + targets = [middle,middle1] + factor = self.segments + dt_target_idx = middle1 + else: + targets = [middle1,last] + factor = self.segments * 2 + dt_target_idx = last + + + # Use copy transforms constraints to position each bone + # exactly in the location respective to its index (between + # the two edges) + make_constraint( self, b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : tweaks['ctrl'][targets[0]], + }) + make_constraint( self, b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : tweaks['ctrl'][targets[1]], + 'influence' : (i - factor) / self.segments + }) + make_constraint( self, b, { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : tweaks['ctrl'][ dt_target_idx ], + }) + + else: + for i,b in enumerate( tweaks['mch'] ): + first = 0 + middle = trunc( len( tweaks['mch'] ) / 2 ) + last = len( tweaks['mch'] ) - 1 + + if i == first or i == middle: + make_constraint( self, b, { + 'constraint' : 'COPY_SCALE', + 'subtarget' : 'root' + }) + elif i != last: + targets = [] + dt_target_idx = middle + factor = 0 + if i < middle: + targets = [first,middle] + else: + targets = [middle,last] + factor = self.segments + dt_target_idx = last + + # Use copy transforms constraints to position each bone + # exactly in the location respective to its index (between + # the two edges) + make_constraint( self, b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : tweaks['ctrl'][targets[0]], + }) + make_constraint( self, b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : tweaks['ctrl'][targets[1]], + 'influence' : (i - factor) / self.segments + }) + make_constraint( self, b, { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : tweaks['ctrl'][ dt_target_idx ], + }) + + # Ctrl bones Locks and Widgets + pb = self.obj.pose.bones + for t in tweaks['ctrl']: + pb[t].lock_rotation = True, False, True + pb[t].lock_scale = False, True, False + + create_sphere_widget(self.obj, t, bone_transform_name=None) + + if self.tweak_layers: + pb[t].bone.layers = self.tweak_layers + + return tweaks + + + def create_def( self, tweaks ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + def_bones = [] + for i,org in enumerate(org_bones): + if i < len(org_bones) - 1: + # Create segments if specified + for j in range( self.segments ): + name = get_bone_name( strip_org(org), 'def' ) + def_name = copy_bone( self.obj, org, name ) + + eb[ def_name ].length /= self.segments + + # If we have more than one segments, place the 2nd and + # onwards on the tail of the previous bone + if j > 0: + put_bone(self.obj, def_name, eb[ def_bones[-1] ].tail) + + def_bones += [ def_name ] + else: + name = get_bone_name( strip_org(org), 'def' ) + def_name = copy_bone( self.obj, org, name ) + def_bones.append( def_name ) + + # Parent deform bones + for i,b in enumerate( def_bones ): + if i > 0: # For all bones but the first (which has no parent) + eb[b].parent = eb[ def_bones[i-1] ] # to previous + eb[b].use_connect = True + + # Constraint def to tweaks + for d,t in zip(def_bones, tweaks): + tidx = tweaks.index(t) + + make_constraint( self, d, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : t + }) + + if tidx != len(tweaks) - 1: + make_constraint( self, d, { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : tweaks[ tidx + 1 ], + }) + + make_constraint( self, d, { + 'constraint' : 'STRETCH_TO', + 'subtarget' : tweaks[ tidx + 1 ], + }) + + # Create bbone segments + for bone in def_bones[:-1]: + self.obj.data.bones[bone].bbone_segments = self.bbones + + self.obj.data.bones[ def_bones[0] ].bbone_in = 0.0 + self.obj.data.bones[ def_bones[-2] ].bbone_out = 0.0 + self.obj.data.bones[ def_bones[-1] ].bbone_in = 0.0 + self.obj.data.bones[ def_bones[-1] ].bbone_out = 0.0 + + + # Rubber hose drivers + pb = self.obj.pose.bones + for i,t in enumerate( tweaks[1:-1] ): + # Create custom property on tweak bone to control rubber hose + name = 'rubber_tweak' + + if i == trunc( len( tweaks[1:-1] ) / 2 ): + pb[t][name] = 0.0 + else: + pb[t][name] = 1.0 + + prop = rna_idprop_ui_prop_get( pb[t], name, create=True ) + + prop["min"] = 0.0 + prop["max"] = 2.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = name + + for j,d in enumerate(def_bones[:-1]): + drvs = {} + if j != 0: + tidx = j + drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_in").driver + + if j != len( def_bones[:-1] ) - 1: + tidx = j + 1 + drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_out").driver + + for d in drvs: + drv = drvs[d] + name = 'rubber_tweak' + drv.type = 'AVERAGE' + var = drv.variables.new() + var.name = name + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = pb[tweaks[d]].path_from_id() + \ + '[' + '"' + name + '"' + ']' + + return def_bones + + + def create_ik( self, parent ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + ctrl = get_bone_name( org_bones[0], 'ctrl', 'ik' ) + mch_ik = get_bone_name( org_bones[0], 'mch', 'ik' ) + mch_target = get_bone_name( org_bones[0], 'mch', 'ik_target' ) + + for o, ik in zip( org_bones, [ ctrl, mch_ik, mch_target ] ): + bone = copy_bone( self.obj, o, ik ) + + if org_bones.index(o) == len( org_bones ) - 1: + eb[ bone ].length /= 4 + + # Create MCH Stretch + mch_str = copy_bone( + self.obj, + org_bones[0], + get_bone_name( org_bones[0], 'mch', 'ik_stretch' ) + ) + + if self.limb_type != 'paw': + eb[ mch_str ].tail = eb[ org_bones[-1] ].head + else: + eb[ mch_str ].tail = eb[ org_bones[-2] ].head + + # Parenting + eb[ ctrl ].parent = eb[ parent ] + eb[ mch_str ].parent = eb[ parent ] + eb[ mch_ik ].parent = eb[ ctrl ] + + + make_constraint( self, mch_ik, { + 'constraint' : 'IK', + 'subtarget' : mch_target, + 'chain_count' : 2, + }) + + pb = self.obj.pose.bones + pb[ mch_ik ].ik_stretch = 0.1 + pb[ ctrl ].ik_stretch = 0.1 + + # IK constraint Rotation locks + for axis in ['x','y','z']: + if axis != self.rot_axis: + setattr( pb[ mch_ik ], 'lock_ik_' + axis, True ) + + # Locks and Widget + pb[ ctrl ].lock_rotation = True, False, True + create_ikarrow_widget( self.obj, ctrl, bone_transform_name=None ) + + return { 'ctrl' : { 'limb' : ctrl }, + 'mch_ik' : mch_ik, + 'mch_target' : mch_target, + 'mch_str' : mch_str + } + + + def create_fk( self, parent ): + org_bones = self.org_bones.copy() + + if self.limb_type == 'paw': # Paw base chain is one bone longer + org_bones.pop() + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + ctrls = [] + + for o in org_bones: + bone = copy_bone( self.obj, o, get_bone_name( o, 'ctrl', 'fk' ) ) + ctrls.append( bone ) + + # MCH + mch = copy_bone( + self.obj, org_bones[-1], get_bone_name( o, 'mch', 'fk' ) + ) + + eb[ mch ].length /= 4 + + # Parenting + eb[ ctrls[0] ].parent = eb[ parent ] + eb[ ctrls[1] ].parent = eb[ ctrls[0] ] + eb[ ctrls[1] ].use_connect = True + eb[ ctrls[2] ].parent = eb[ mch ] + eb[ mch ].parent = eb[ ctrls[1] ] + eb[ mch ].use_connect = True + + # Constrain MCH's scale to root + make_constraint( self, mch, { + 'constraint' : 'COPY_SCALE', + 'subtarget' : 'root' + }) + + # Locks and widgets + pb = self.obj.pose.bones + pb[ ctrls[2] ].lock_location = True, True, True + + create_limb_widget( self.obj, ctrls[0] ) + create_limb_widget( self.obj, ctrls[1] ) + + create_circle_widget(self.obj, ctrls[2], radius=0.4, head_tail=0.0) + + for c in ctrls: + if self.fk_layers: + pb[c].bone.layers = self.fk_layers + + 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 + # re-parent ORGs in a connected chain + for i,o in enumerate(org): + if i > 0: + eb[o].parent = eb[ org[i-1] ] + if i <= len(org)-1: + eb[o].use_connect = True + + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + pb_parent = pb[ parent ] + + # Create ik/fk switch property + pb_parent['IK/FK'] = 0.0 + prop = rna_idprop_ui_prop_get( pb_parent, 'IK/FK', create=True ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = 'IK/FK Switch' + + # Constrain org to IK and FK bones + iks = [ ik['ctrl']['limb'] ] + iks += [ ik[k] for k in [ 'mch_ik', 'mch_target'] ] + + for o, i, f in zip( org, iks, fk ): + make_constraint( self, o, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : i + }) + make_constraint( self, o, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : f + }) + + # Add driver to relevant constraint + drv = pb[o].constraints[-1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop.name + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + + + 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 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 + + 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'] ) + + self.org_parenting_and_switch( + self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] + ) + + bones = self.create_terminal( self.limb_type, bones ) + + return [ create_script( bones, self.limb_type ) ] + +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', ''), + ('z', 'Z', '') + ] + params.rotation_axis = bpy.props.EnumProperty( + items = items, + name = "Rotation Axis", + default = 'x' + ) + + params.segments = bpy.props.IntProperty( + name = 'limb segments', + default = 2, + min = 1, + description = 'Number of segments' + ) + + params.bbones = bpy.props.IntProperty( + name = 'bbone segments', + default = 10, + min = 1, + description = 'Number of segments' + ) + + # 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) ] ) + ) + + # Setting up extra layers for the FK and tweak + params.fk_extra_layers = bpy.props.BoolProperty( + name = "fk_extra_layers", + default = True, + description = "" + ) + + params.fk_layers = bpy.props.BoolVectorProperty( + size = 32, + description = "Layers for the FK 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, "limb_type") + + r = layout.row() + r.prop(params, "rotation_axis") + + r = layout.row() + r.prop(params, "segments") + + r = layout.row() + r.prop(params, "bbones") + + for layer in [ 'fk', 'tweak' ]: + r = layout.row() + r.prop(params, layer + "_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, layer + "_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range(16,24): + row.prop(params, layer + "_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, layer + "_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range(24,32): + row.prop(params, layer + "_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('upper_arm.L') + bone.head[:] = -0.0016, 0.0060, -0.0012 + bone.tail[:] = 0.2455, 0.0678, -0.1367 + bone.roll = 2.0724 + bone.use_connect = False + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('forearm.L') + bone.head[:] = 0.2455, 0.0678, -0.1367 + bone.tail[:] = 0.4625, 0.0285, -0.2797 + bone.roll = 2.1535 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.L']] + bones['forearm.L'] = bone.name + bone = arm.edit_bones.new('hand.L') + bone.head[:] = 0.4625, 0.0285, -0.2797 + bone.tail[:] = 0.5265, 0.0205, -0.3273 + bone.roll = 2.2103 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.L']] + bones['hand.L'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'pitchipoy.limbs.super_limb' + 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' + try: + pbone.rigify_parameters.separate_ik_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.ik_layers = [ + False, False, False, False, False, False, False, False, True, False, + False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, + False, False + ] + except AttributeError: + pass + try: + pbone.rigify_parameters.separate_hose_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.hose_layers = [ + False, False, False, False, False, False, False, False, False, True, + False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, + False, False + ] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [ + False, False, False, False, False, False, False, False, False, True, + False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, + False, False + ] + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [ + False, False, False, False, False, False, False, False, True, False, + False, False, False, False, False, False, False, False, False, False, + False, False, False, False, False, False, False, False, False, False, + False, False + ] + except AttributeError: + pass + pbone = obj.pose.bones[bones['forearm.L']] + 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 = obj.pose.bones[bones['hand.L']] + 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' + + 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 diff --git a/rigify/legacy/rigs/pitchipoy/limbs/ui.py b/rigify/legacy/rigs/pitchipoy/limbs/ui.py new file mode 100644 index 00000000..37921dc0 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/limbs/ui.py @@ -0,0 +1,143 @@ +script_arm = """ +controls = [%s] +tweaks = [%s] +ik_ctrl = [%s] +fk_ctrl = '%s' +parent = '%s' + +# IK/FK Switch on all Control Bones +if is_selected( controls ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + props = layout.operator("pose.rigify_arm_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_ctrl + ")") + props.uarm_fk = controls[1] + props.farm_fk = controls[2] + props.hand_fk = controls[3] + props.uarm_ik = controls[0] + props.farm_ik = ik_ctrl[1] + props.hand_ik = controls[4] + props = layout.operator("pose.rigify_arm_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_ctrl + ")") + props.uarm_fk = controls[1] + props.farm_fk = controls[2] + props.hand_fk = controls[3] + props.uarm_ik = controls[0] + props.farm_ik = ik_ctrl[1] + props.hand_ik = controls[4] + props.pole = "" + + +# BBone rubber hose on each Respective Tweak +for t in tweaks: + if is_selected( t ): + layout.prop( pose_bones[ t ], '["%s"]', slider = True ) + +# IK Stretch on IK Control bone +if is_selected( ik_ctrl ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + +# FK limb follow +if is_selected( fk_ctrl ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) +""" + +script_leg = """ +controls = [%s] +tweaks = [%s] +ik_ctrl = [%s] +fk_ctrl = '%s' +parent = '%s' + +# IK/FK Switch on all Control Bones +if is_selected( controls ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + props = layout.operator("pose.rigify_leg_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_ctrl + ")") + props.thigh_fk = controls[1] + props.shin_fk = controls[2] + props.foot_fk = controls[3] + props.mfoot_fk = controls[7] + props.thigh_ik = controls[0] + props.shin_ik = ik_ctrl[1] + props.foot_ik = ik_ctrl[2] + props.mfoot_ik = ik_ctrl[2] + props = layout.operator("pose.rigify_leg_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_ctrl + ")") + props.thigh_fk = controls[1] + props.shin_fk = controls[2] + props.foot_fk = controls[3] + props.mfoot_fk = controls[7] + props.thigh_ik = controls[0] + props.shin_ik = ik_ctrl[1] + props.foot_ik = controls[6] + props.pole = "" + props.footroll = controls[5] + props.mfoot_ik = ik_ctrl[2] + +# BBone rubber hose on each Respective Tweak +for t in tweaks: + if is_selected( t ): + layout.prop( pose_bones[ t ], '["%s"]', slider = True ) + +# IK Stretch on IK Control bone +if is_selected( ik_ctrl ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + +# FK limb follow +if is_selected( fk_ctrl ): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) +""" + +def create_script( bones, limb_type=None): + # All ctrls have IK/FK switch + controls = [ bones['ik']['ctrl']['limb'] ] + bones['fk']['ctrl'] + controls += bones['ik']['ctrl']['terminal'] + controls += [ bones['fk']['mch'] ] + + controls_string = ", ".join(["'" + x + "'" for x in controls]) + + # All tweaks have their own bbone prop + tweaks = bones['tweak']['ctrl'][1:-1] + tweaks_string = ", ".join(["'" + x + "'" for x in tweaks]) + + # IK ctrl has IK stretch + ik_ctrl = [ bones['ik']['ctrl']['terminal'][-1] ] + ik_ctrl += [ bones['ik']['mch_ik'] ] + ik_ctrl += [ bones['ik']['mch_target'] ] + + ik_ctrl_string = ", ".join(["'" + x + "'" for x in ik_ctrl]) + + if limb_type == 'arm': + return script_arm % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['parent'], + 'IK/FK', + 'rubber_tweak', + 'IK_Strertch', + 'FK_limb_follow' + ) + + elif limb_type == 'leg': + return script_leg % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['parent'], + 'IK/FK', + 'rubber_tweak', + 'IK_Strertch', + 'FK_limb_follow' + ) + + elif limb_type == 'paw': + return script_leg % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['parent'], + 'IK/FK', + 'rubber_tweak', + 'IK_Strertch', + 'FK_limb_follow' + ) diff --git a/rigify/legacy/rigs/pitchipoy/simple_tentacle.py b/rigify/legacy/rigs/pitchipoy/simple_tentacle.py new file mode 100644 index 00000000..4edb15e6 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/simple_tentacle.py @@ -0,0 +1,350 @@ +import bpy +from ...utils import copy_bone +from ...utils import strip_org, make_deformer_name, connected_children_names +from ...utils import make_mechanism_name, put_bone, create_sphere_widget +from ...utils import create_widget, create_circle_widget +from ...utils import MetarigError +from rna_prop_ui import rna_idprop_ui_prop_get + +class Rig: + + def __init__(self, obj, bone_name, params): + self.obj = obj + self.org_bones = [bone_name] + connected_children_names(obj, bone_name) + self.params = params + + self.copy_rotaion_axes = params.copy_rotaion_axes + + if params.tweak_extra_layers: + self.tweak_layers = list( params.tweak_layers ) + else: + self.tweak_layers = None + + if len(self.org_bones) <= 1: + raise MetarigError( + "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name)) + ) + + + def make_controls( self ): + + bpy.ops.object.mode_set(mode ='EDIT') + org_bones = self.org_bones + + ctrl_chain = [] + for i in range( len( org_bones ) ): + name = org_bones[i] + + ctrl_bone = copy_bone( + self.obj, + name, + strip_org(name) + ) + + ctrl_chain.append( ctrl_bone ) + + # Make widgets + bpy.ops.object.mode_set(mode ='OBJECT') + + for ctrl in ctrl_chain: + create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5) + + return ctrl_chain + + + def make_tweaks( self ): + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + org_bones = self.org_bones + + tweak_chain = [] + for i in range( len( org_bones ) + 1 ): + if i == len( org_bones ): + # Make final tweak at the tip of the tentacle + name = org_bones[i-1] + else: + name = org_bones[i] + + tweak_bone = copy_bone( + self.obj, + name, + "tweak_" + strip_org(name) + ) + + tweak_e = eb[ tweak_bone ] + + tweak_e.length /= 2 # Set size to half + + if i == len( org_bones ): + # Position final tweak at the tip + put_bone( self.obj, tweak_bone, eb[ org_bones[-1]].tail ) + + tweak_chain.append( tweak_bone ) + + # Make widgets + bpy.ops.object.mode_set(mode = 'OBJECT') + + for tweak in tweak_chain: + create_sphere_widget( self.obj, tweak ) + + tweak_pb = self.obj.pose.bones[ tweak ] + + # Set locks + if tweak_chain.index( tweak ) != len( tweak_chain ) - 1: + tweak_pb.lock_rotation = (True, False, True) + tweak_pb.lock_scale = (False, True, False) + else: + tweak_pb.lock_rotation_w = True + tweak_pb.lock_rotation = (True, True, True) + tweak_pb.lock_scale = (True, True, True) + + # Set up tweak bone layers + if self.tweak_layers: + tweak_pb.bone.layers = self.tweak_layers + + return tweak_chain + + + def make_deform( self ): + + bpy.ops.object.mode_set(mode ='EDIT') + org_bones = self.org_bones + + def_chain = [] + for i in range( len( org_bones ) ): + name = org_bones[i] + + def_bone = copy_bone( + self.obj, + name, + make_deformer_name(strip_org(name)) + ) + + def_chain.append( def_bone ) + + return def_chain + + + def parent_bones( self, all_bones ): + + bpy.ops.object.mode_set(mode ='EDIT') + org_bones = self.org_bones + eb = self.obj.data.edit_bones + + # Parent control bones + for bone in all_bones['control'][1:]: + previous_index = all_bones['control'].index( bone ) - 1 + eb[ bone ].parent = eb[ all_bones['control'][previous_index] ] + + # Parent tweak bones + tweaks = all_bones['tweak'] + for tweak in all_bones['tweak']: + parent = '' + if tweaks.index( tweak ) == len( tweaks ) - 1: + parent = all_bones['control'][ -1 ] + else: + parent = all_bones['control'][ tweaks.index( tweak ) ] + + eb[ tweak ].parent = eb[ parent ] + + # Parent deform bones + for bone in all_bones['deform'][1:]: + previous_index = all_bones['deform'].index( bone ) - 1 + + eb[ bone ].parent = eb[ all_bones['deform'][previous_index] ] + eb[ bone ].use_connect = True + + # Parent org bones ( to tweaks by default, or to the controls ) + for org, tweak in zip( org_bones, all_bones['tweak'] ): + eb[ org ].parent = eb[ tweak ] + + + def make_constraints( self, all_bones ): + + bpy.ops.object.mode_set(mode ='OBJECT') + org_bones = self.org_bones + pb = self.obj.pose.bones + + # Deform bones' constraints + ctrls = all_bones['control'] + tweaks = all_bones['tweak' ] + deforms = all_bones['deform' ] + + for deform, tweak, ctrl in zip( deforms, tweaks, ctrls ): + con = pb[deform].constraints.new('COPY_TRANSFORMS') + con.target = self.obj + con.subtarget = tweak + + con = pb[deform].constraints.new('DAMPED_TRACK') + con.target = self.obj + con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ] + + con = pb[deform].constraints.new('STRETCH_TO') + con.target = self.obj + con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ] + + # Control bones' constraints + if ctrl != ctrls[0]: + con = pb[ctrl].constraints.new('COPY_ROTATION') + con.target = self.obj + con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ] + for i, prop in enumerate( [ 'use_x', 'use_y', 'use_z' ] ): + if self.copy_rotaion_axes[i]: + setattr( con, prop, True ) + else: + setattr( con, prop, False ) + con.use_offset = True + con.target_space = 'LOCAL' + con.owner_space = 'LOCAL' + + + + def generate(self): + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Clear all initial parenting + for bone in self.org_bones: + # eb[ bone ].parent = None + eb[ bone ].use_connect = False + + # Creating all bones + ctrl_chain = self.make_controls() + tweak_chain = self.make_tweaks() + def_chain = self.make_deform() + + all_bones = { + 'control' : ctrl_chain, + 'tweak' : tweak_chain, + 'deform' : def_chain + } + + self.make_constraints( all_bones ) + self.parent_bones( all_bones ) + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + params.copy_rotaion_axes = bpy.props.BoolVectorProperty( + size = 3, + description = "Layers for the tweak controls to be on", + default = tuple( [ i == 0 for i in range(0, 3) ] ) + ) + + # Setting up extra tweak layers + 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() + col = r.column(align=True) + row = col.row(align=True) + for i,axis in enumerate( [ 'x', 'y', 'z' ] ): + row.prop(params, "copy_rotaion_axes", index=i, toggle=True, text=axis) + + 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 ): # Layers 0-7 + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range( 16, 24 ): # Layers 16-23 + 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 ): # Layers 8-15 + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range( 24, 32 ): # Layers 24-31 + 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('Bone') + bone.head[:] = 0.0000, 0.0000, 0.0000 + bone.tail[:] = 0.0000, 0.0000, 0.3333 + bone.roll = 0.0000 + bone.use_connect = False + bones['Bone'] = bone.name + + bone = arm.edit_bones.new('Bone.002') + bone.head[:] = 0.0000, 0.0000, 0.3333 + bone.tail[:] = 0.0000, 0.0000, 0.6667 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Bone']] + bones['Bone.002'] = bone.name + + bone = arm.edit_bones.new('Bone.001') + bone.head[:] = 0.0000, 0.0000, 0.6667 + bone.tail[:] = 0.0000, 0.0000, 1.0000 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['Bone.002']] + bones['Bone.001'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['Bone']] + pbone.rigify_type = 'pitchipoy.simple_tentacle' + 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 = obj.pose.bones[bones['Bone.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 = obj.pose.bones[bones['Bone.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' + + 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 diff --git a/rigify/legacy/rigs/pitchipoy/super_copy.py b/rigify/legacy/rigs/pitchipoy/super_copy.py new file mode 100644 index 00000000..d05d68c4 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_copy.py @@ -0,0 +1,159 @@ +#====================== 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 bpy + +from ...utils import copy_bone +from ...utils import strip_org, make_deformer_name +from ...utils import create_bone_widget, create_circle_widget + + +class Rig: + """ A "copy" rig. All it does is duplicate the original bone and + constrain it. + This is a control and deformation rig. + + """ + def __init__(self, obj, bone, params): + """ Gather and validate data about the rig. + """ + self.obj = obj + self.org_bone = bone + self.org_name = strip_org(bone) + self.params = params + self.make_control = params.make_control + self.make_widget = params.make_widget + self.make_deform = params.make_deform + + def generate(self): + """ Generate the rig. + Do NOT modify any of the original bones, except for adding constraints. + The main armature should be selected and active before this is called. + + """ + bpy.ops.object.mode_set(mode='EDIT') + + # Make a control bone (copy of original). + if self.make_control: + bone = copy_bone(self.obj, self.org_bone, self.org_name) + + # Make a deformation bone (copy of original, child of original). + if self.make_deform: + def_bone = copy_bone(self.obj, self.org_bone, make_deformer_name(self.org_name)) + + # Get edit bones + eb = self.obj.data.edit_bones + # UNUSED + # if self.make_control: + # bone_e = eb[bone] + if self.make_deform: + def_bone_e = eb[def_bone] + + # Parent + if self.make_deform: + def_bone_e.use_connect = False + def_bone_e.parent = eb[self.org_bone] + + bpy.ops.object.mode_set(mode='OBJECT') + pb = self.obj.pose.bones + + if self.make_control: + # Constrain the original bone. + con = pb[self.org_bone].constraints.new('COPY_TRANSFORMS') + con.name = "copy_transforms" + con.target = self.obj + con.subtarget = bone + + # Create control widget + if self.make_widget: + create_circle_widget(self.obj, bone, radius = 0.5 ) + else: + create_bone_widget(self.obj, bone, radius = 0.5 ) + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + params.make_control = bpy.props.BoolProperty( + name = "Control", + default = True, + description = "Create a control bone for the copy" + ) + + params.make_widget = bpy.props.BoolProperty( + name = "Widget", + default = True, + description = "Choose a widget for the bone control" + ) + + params.make_deform = bpy.props.BoolProperty( + name = "Deform", + default = True, + description = "Create a deform bone for the copy" + ) + + +def parameters_ui(layout, params): + """ Create the ui for the rig parameters. + """ + r = layout.row() + r.prop(params, "make_control") + r = layout.row() + r.prop(params, "make_widget") + r = layout.row() + r.prop(params, "make_deform") + + +def create_sample(obj): + """ Create a sample metarig for this rig type. + """ + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + bones = {} + + bone = arm.edit_bones.new('Bone') + bone.head[:] = 0.0000, 0.0000, 0.0000 + bone.tail[:] = 0.0000, 0.0000, 0.2000 + bone.roll = 0.0000 + bone.use_connect = False + bones['Bone'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['Bone']] + pbone.rigify_type = 'basic.copy' + 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' + + 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 diff --git a/rigify/legacy/rigs/pitchipoy/super_face.py b/rigify/legacy/rigs/pitchipoy/super_face.py new file mode 100644 index 00000000..9928864f --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_face.py @@ -0,0 +1,2400 @@ +import bpy, re +from mathutils import Vector +from ...utils import copy_bone, flip_bone +from ...utils import org, strip_org, make_deformer_name, connected_children_names, make_mechanism_name +from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_cube_widget +from ...utils import MetarigError +from rna_prop_ui import rna_idprop_ui_prop_get +from .super_widgets import create_face_widget, create_eye_widget, create_eyes_widget, create_ear_widget, create_jaw_widget, create_teeth_widget + + +script = """ +all_controls = [%s] +jaw_ctrl_name = '%s' +eyes_ctrl_name = '%s' + +if is_selected(all_controls): + layout.prop(pose_bones[jaw_ctrl_name], '["%s"]', slider=True) + layout.prop(pose_bones[eyes_ctrl_name], '["%s"]', slider=True) +""" +class Rig: + + def __init__(self, obj, bone_name, params): + self.obj = obj + + b = self.obj.data.bones + + children = [ + "nose", "lip.T.L", "lip.B.L", "jaw", "ear.L", "ear.R", "lip.T.R", + "lip.B.R", "brow.B.L", "lid.T.L", "brow.B.R", "lid.T.R", + "forehead.L", "forehead.R", "forehead.L.001", "forehead.R.001", + "forehead.L.002", "forehead.R.002", "eye.L", "eye.R", "cheek.T.L", + "cheek.T.R", "teeth.T", "teeth.B", "tongue", "temple.L", + "temple.R" + ] + + #create_pose_lib( self.obj ) + + children = [ org(b) for b in children ] + grand_children = [] + + for child in children: + grand_children += connected_children_names( self.obj, child ) + + self.org_bones = [bone_name] + children + grand_children + self.face_length = obj.data.edit_bones[ self.org_bones[0] ].length + self.params = params + + if params.primary_layers_extra: + self.primary_layers = list(params.primary_layers) + else: + self.primary_layers = None + + if params.secondary_layers_extra: + self.secondary_layers = list(params.secondary_layers) + else: + self.secondary_layers = None + + def symmetrical_split( self, bones ): + + # RE pattern match right or left parts + # match the letter "L" (or "R"), followed by an optional dot (".") + # and 0 or more digits at the end of the the string + left_pattern = 'L\.?\d*$' + right_pattern = 'R\.?\d*$' + + left = sorted( [ name for name in bones if re.search( left_pattern, name ) ] ) + right = sorted( [ name for name in bones if re.search( right_pattern, name ) ] ) + + return left, right + + def create_deformation( self ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + def_bones = [] + for org in org_bones: + if 'face' in org or 'teeth' in org or 'eye' in org: + continue + + def_name = make_deformer_name( strip_org( org ) ) + def_name = copy_bone( self.obj, org, def_name ) + def_bones.append( def_name ) + + eb[def_name].use_connect = False + eb[def_name].parent = None + + brow_top_names = [ bone for bone in def_bones if 'brow.T' in bone ] + forehead_names = [ bone for bone in def_bones if 'forehead' in bone ] + + brow_left, brow_right = self.symmetrical_split( brow_top_names ) + forehead_left, forehead_right = self.symmetrical_split( forehead_names ) + + brow_left = brow_left[1:] + brow_right = brow_right[1:] + brow_left.reverse() + brow_right.reverse() + + for browL, browR, foreheadL, foreheadR in zip( + brow_left, brow_right, forehead_left, forehead_right ): + + eb[foreheadL].tail = eb[browL].head + eb[foreheadR].tail = eb[browR].head + + return { 'all' : def_bones } + + + def create_ctrl( self, bones ): + org_bones = self.org_bones + + ## create control bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # eyes ctrls + eyeL_e = eb[ bones['eyes'][0] ] + eyeR_e = eb[ bones['eyes'][1] ] + + distance = ( eyeL_e.head - eyeR_e.head ) * 3 + distance = distance.cross( (0, 0, 1) ) + eye_length = eyeL_e.length + + eyeL_ctrl_name = strip_org( bones['eyes'][0] ) + eyeR_ctrl_name = strip_org( bones['eyes'][1] ) + + eyeL_ctrl_name = copy_bone( self.obj, bones['eyes'][0], eyeL_ctrl_name ) + eyeR_ctrl_name = copy_bone( self.obj, bones['eyes'][1], eyeR_ctrl_name ) + eyes_ctrl_name = copy_bone( self.obj, bones['eyes'][0], 'eyes' ) + + eyeL_ctrl_e = eb[ eyeL_ctrl_name ] + eyeR_ctrl_e = eb[ eyeR_ctrl_name ] + eyes_ctrl_e = eb[ 'eyes' ] + + eyeL_ctrl_e.head += distance + eyeR_ctrl_e.head += distance + eyes_ctrl_e.head[:] = ( eyeL_ctrl_e.head + eyeR_ctrl_e.head ) / 2 + + for bone in [ eyeL_ctrl_e, eyeR_ctrl_e, eyes_ctrl_e ]: + bone.tail[:] = bone.head + Vector( [ 0, 0, eye_length * 0.75 ] ) + + ## Widget for transforming the both eyes + eye_master_names = [] + for bone in bones['eyes']: + eye_master = copy_bone( + self.obj, + bone, + 'master_' + strip_org(bone) + ) + + eye_master_names.append( eye_master ) + + ## turbo: adding a master nose for transforming the whole nose + master_nose = copy_bone(self.obj, 'ORG-nose.004', 'nose_master') + eb[master_nose].tail[:] = \ + eb[master_nose].head + Vector([0, self.face_length / -4, 0]) + + # ears ctrls + earL_name = strip_org( bones['ears'][0] ) + earR_name = strip_org( bones['ears'][1] ) + + earL_ctrl_name = copy_bone( self.obj, org( bones['ears'][0] ), earL_name ) + earR_ctrl_name = copy_bone( self.obj, org( bones['ears'][1] ), earR_name ) + + # jaw ctrl + jaw_ctrl_name = strip_org( bones['jaw'][2] ) + '_master' + jaw_ctrl_name = copy_bone( self.obj, bones['jaw'][2], jaw_ctrl_name ) + + jawL_org_e = eb[ bones['jaw'][0] ] + jawR_org_e = eb[ bones['jaw'][1] ] + jaw_org_e = eb[ bones['jaw'][2] ] + + eb[ jaw_ctrl_name ].head[:] = ( jawL_org_e.head + jawR_org_e.head ) / 2 + + # teeth ctrls + teethT_name = strip_org( bones['teeth'][0] ) + teethB_name = strip_org( bones['teeth'][1] ) + + teethT_ctrl_name = copy_bone( self.obj, org( bones['teeth'][0] ), teethT_name ) + teethB_ctrl_name = copy_bone( self.obj, org( bones['teeth'][1] ), teethB_name ) + + # tongue ctrl + tongue_org = bones['tongue'].pop() + tongue_name = strip_org( tongue_org ) + '_master' + + tongue_ctrl_name = copy_bone( self.obj, tongue_org, tongue_name ) + + flip_bone( self.obj, tongue_ctrl_name ) + + ## Assign widgets + bpy.ops.object.mode_set(mode ='OBJECT') + + # Assign each eye widgets + create_eye_widget( self.obj, eyeL_ctrl_name ) + create_eye_widget( self.obj, eyeR_ctrl_name ) + + # Assign eyes widgets + create_eyes_widget( self.obj, eyes_ctrl_name ) + + # Assign each eye_master widgets + for master in eye_master_names: + create_square_widget(self.obj, master) + + # Assign nose_master widget + create_square_widget( self.obj, master_nose, size = 1 ) + + # Assign ears widget + create_ear_widget( self.obj, earL_ctrl_name ) + create_ear_widget( self.obj, earR_ctrl_name ) + + # Assign jaw widget + create_jaw_widget( self.obj, jaw_ctrl_name ) + + # Assign teeth widget + create_teeth_widget( self.obj, teethT_ctrl_name ) + create_teeth_widget( self.obj, teethB_ctrl_name ) + + # Assign tongue widget ( using the jaw widget ) + create_jaw_widget( self.obj, tongue_ctrl_name ) + + return { + 'eyes' : [ + eyeL_ctrl_name, + eyeR_ctrl_name, + eyes_ctrl_name, + ] + eye_master_names, + 'ears' : [ earL_ctrl_name, earR_ctrl_name ], + 'jaw' : [ jaw_ctrl_name ], + 'teeth' : [ teethT_ctrl_name, teethB_ctrl_name ], + 'tongue' : [ tongue_ctrl_name ], + 'nose' : [ master_nose ] + } + + + def create_tweak( self, bones, uniques, tails ): + org_bones = self.org_bones + + ## create tweak bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + tweaks = [] + + for bone in bones + list( uniques.keys() ): + + tweak_name = strip_org( bone ) + + # pick name for unique bone from the uniques dictionary + if bone in list( uniques.keys() ): + tweak_name = uniques[bone] + + tweak_name = copy_bone( self.obj, bone, tweak_name ) + eb[ tweak_name ].use_connect = False + eb[ tweak_name ].parent = None + + tweaks.append( tweak_name ) + + eb[ tweak_name ].tail[:] = \ + eb[ tweak_name ].head + Vector(( 0, 0, self.face_length / 7 )) + + # create tail bone + if bone in tails: + if 'lip.T.L.001' in bone: + tweak_name = copy_bone( self.obj, bone, 'lips.L' ) + elif 'lip.T.R.001' in bone: + tweak_name = copy_bone( self.obj, bone, 'lips.R' ) + else: + tweak_name = copy_bone( self.obj, bone, tweak_name ) + + eb[ tweak_name ].use_connect = False + eb[ tweak_name ].parent = None + + eb[ tweak_name ].head = eb[ bone ].tail + eb[ tweak_name ].tail[:] = \ + eb[ tweak_name ].head + Vector(( 0, 0, self.face_length / 7 )) + + tweaks.append( tweak_name ) + + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + primary_tweaks = [ + "lid.B.L.002", "lid.T.L.002", "lid.B.R.002", "lid.T.R.002", + "chin", "brow.T.L.001", "brow.T.L.002", "brow.T.L.003", + "brow.T.R.001", "brow.T.R.002", "brow.T.R.003", "lip.B", + "lip.B.L.001", "lip.B.R.001", "cheek.B.L.001", "cheek.B.R.001", + "lips.L", "lips.R", "lip.T.L.001", "lip.T.R.001", "lip.T", + "nose.002", "nose.L.001", "nose.R.001" + ] + + for bone in tweaks: + if bone in primary_tweaks: + if self.primary_layers: + pb[bone].bone.layers = self.primary_layers + create_face_widget( self.obj, bone, size = 1.5 ) + else: + if self.secondary_layers: + pb[bone].bone.layers = self.secondary_layers + create_face_widget( self.obj, bone ) + + return { 'all' : tweaks } + + + def all_controls( self ): + org_bones = self.org_bones + + org_tongue_bones = sorted([ bone for bone in org_bones if 'tongue' in bone ]) + + org_to_ctrls = { + 'eyes' : [ 'eye.L', 'eye.R' ], + 'ears' : [ 'ear.L', 'ear.R' ], + 'jaw' : [ 'jaw.L', 'jaw.R', 'jaw' ], + 'teeth' : [ 'teeth.T', 'teeth.B' ], + 'tongue' : [ org_tongue_bones[0] ] + } + + tweak_unique = { 'lip.T.L' : 'lip.T', + 'lip.B.L' : 'lip.B' } + + org_to_ctrls = { key : [ org( bone ) for bone in org_to_ctrls[key] ] for key in org_to_ctrls.keys() } + tweak_unique = { org( key ) : tweak_unique[key] for key in tweak_unique.keys() } + + tweak_exceptions = [] # bones not used to create tweaks + tweak_exceptions += [ bone for bone in org_bones if 'forehead' in bone or 'temple' in bone ] + + tweak_tail = [ 'brow.B.L.003', 'brow.B.R.003', 'nose.004', 'chin.001' ] + tweak_tail += [ 'lip.T.L.001', 'lip.T.R.001', 'tongue.002' ] + + tweak_exceptions += [ 'lip.T.R', 'lip.B.R', 'ear.L.001', 'ear.R.001' ] + list(tweak_unique.keys()) + tweak_exceptions += [ 'face', 'cheek.T.L', 'cheek.T.R', 'cheek.B.L', 'cheek.B.R' ] + tweak_exceptions += [ 'ear.L', 'ear.R', 'eye.L', 'eye.R' ] + + tweak_exceptions += org_to_ctrls.keys() + tweak_exceptions += org_to_ctrls['teeth'] + + tweak_exceptions.pop( tweak_exceptions.index('tongue') ) + tweak_exceptions.pop( tweak_exceptions.index('jaw') ) + + tweak_exceptions = [ org( bone ) for bone in tweak_exceptions ] + tweak_tail = [ org( bone ) for bone in tweak_tail ] + + org_to_tweak = sorted( [ bone for bone in org_bones if bone not in tweak_exceptions ] ) + + ctrls = self.create_ctrl( org_to_ctrls ) + tweaks = self.create_tweak( org_to_tweak, tweak_unique, tweak_tail ) + + return { 'ctrls' : ctrls, 'tweaks' : tweaks }, tweak_unique + + def create_mch( self, jaw_ctrl, tongue_ctrl ): + org_bones = self.org_bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Create eyes mch bones + eyes = [ bone for bone in org_bones if 'eye' in bone ] + + mch_bones = { strip_org( eye ) : [] for eye in eyes } + + for eye in eyes: + mch_name = make_mechanism_name( strip_org( eye ) ) + mch_name = copy_bone( self.obj, eye, mch_name ) + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + mch_bones[ strip_org( eye ) ].append( mch_name ) + + mch_name = copy_bone( self.obj, eye, mch_name ) + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + mch_bones[ strip_org( eye ) ].append( mch_name ) + + eb[ mch_name ].head[:] = eb[ mch_name ].tail + eb[ mch_name ].tail[:] = eb[ mch_name ].head + Vector( ( 0, 0, 0.005 ) ) + + # Create the eyes' parent mch + face = [ bone for bone in org_bones if 'face' in bone ].pop() + + mch_name = 'eyes_parent' + mch_name = make_mechanism_name( mch_name ) + mch_name = copy_bone( self.obj, face, mch_name ) + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + eb[ mch_name ].length /= 4 + + mch_bones['eyes_parent'] = [ mch_name ] + + # Create the lids' mch bones + all_lids = [ bone for bone in org_bones if 'lid' in bone ] + lids_L, lids_R = self.symmetrical_split( all_lids ) + + all_lids = [ lids_L, lids_R ] + + mch_bones['lids'] = [] + + for i in range( 2 ): + for bone in all_lids[i]: + mch_name = make_mechanism_name( strip_org( bone ) ) + mch_name = copy_bone( self.obj, eyes[i], mch_name ) + + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + eb[ mch_name ].tail[:] = eb[ bone ].head + + mch_bones['lids'].append( mch_name ) + + mch_bones['jaw'] = [] + + length_subtractor = eb[ jaw_ctrl ].length / 6 + # Create the jaw mch bones + for i in range( 6 ): + if i == 0: + mch_name = make_mechanism_name( 'mouth_lock' ) + else: + mch_name = make_mechanism_name( jaw_ctrl ) + + mch_name = copy_bone( self.obj, jaw_ctrl, mch_name ) + + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + eb[ mch_name ].length = eb[ jaw_ctrl ].length - length_subtractor * i + + mch_bones['jaw'].append( mch_name ) + + # Tongue mch bones + + mch_bones['tongue'] = [] + + # create mch bones for all tongue org_bones except the first one + for bone in sorted([ org for org in org_bones if 'tongue' in org ])[1:]: + mch_name = make_mechanism_name( strip_org( bone ) ) + mch_name = copy_bone( self.obj, tongue_ctrl, mch_name ) + + eb[ mch_name ].use_connect = False + eb[ mch_name ].parent = None + + mch_bones['tongue'].append( mch_name ) + + return mch_bones + + def parent_bones( self, all_bones, tweak_unique ): + org_bones = self.org_bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + face_name = [ bone for bone in org_bones if 'face' in bone ].pop() + + # Initially parenting all bones to the face org bone. + for category in list( all_bones.keys() ): + for area in list( all_bones[category] ): + for bone in all_bones[category][area]: + eb[ bone ].parent = eb[ face_name ] + + ## Parenting all deformation bones and org bones + + # Parent all the deformation bones that have respective tweaks + def_tweaks = [ bone for bone in all_bones['deform']['all'] if bone[4:] in all_bones['tweaks']['all'] ] + + # Parent all org bones to the ORG-face + for bone in [ bone for bone in org_bones if 'face' not in bone ]: + eb[ bone ].parent = eb[ org('face') ] + + for bone in def_tweaks: + # the def and the matching org bone are parented to their corresponding tweak, + # whose name is the same as that of the def bone, without the "DEF-" (first 4 chars) + eb[ bone ].parent = eb[ bone[4:] ] + eb[ org( bone[4:] ) ].parent = eb[ bone[4:] ] + + # Parent ORG eyes to corresponding mch bones + for bone in [ bone for bone in org_bones if 'eye' in bone ]: + eb[ bone ].parent = eb[ make_mechanism_name( strip_org( bone ) ) ] + + for lip_tweak in list( tweak_unique.values() ): + # find the def bones that match unique lip_tweaks by slicing [4:-2] + # example: 'lip.B' matches 'DEF-lip.B.R' and 'DEF-lip.B.L' if + # you cut off the "DEF-" [4:] and the ".L" or ".R" [:-2] + lip_defs = [ bone for bone in all_bones['deform']['all'] if bone[4:-2] == lip_tweak ] + + for bone in lip_defs: + eb[bone].parent = eb[ lip_tweak ] + + # parent cheek bones top respetive tweaks + lips = [ 'lips.L', 'lips.R' ] + brows = [ 'brow.T.L', 'brow.T.R' ] + cheekB_defs = [ 'DEF-cheek.B.L', 'DEF-cheek.B.R' ] + cheekT_defs = [ 'DEF-cheek.T.L', 'DEF-cheek.T.R' ] + + for lip, brow, cheekB, cheekT in zip( lips, brows, cheekB_defs, cheekT_defs ): + eb[ cheekB ].parent = eb[ lip ] + eb[ cheekT ].parent = eb[ brow ] + + # parent ear deform bones to their controls + ear_defs = [ 'DEF-ear.L', 'DEF-ear.L.001', 'DEF-ear.R', 'DEF-ear.R.001' ] + ear_ctrls = [ 'ear.L', 'ear.R' ] + + eb[ 'DEF-jaw' ].parent = eb[ 'jaw' ] # Parent jaw def bone to jaw tweak + + for ear_ctrl in ear_ctrls: + for ear_def in ear_defs: + if ear_ctrl in ear_def: + eb[ ear_def ].parent = eb[ ear_ctrl ] + + # Parent eyelid deform bones (each lid def bone is parented to its respective MCH bone) + def_lids = [ bone for bone in all_bones['deform']['all'] if 'lid' in bone ] + + for bone in def_lids: + mch = make_mechanism_name( bone[4:] ) + eb[ bone ].parent = eb[ mch ] + + ## Parenting all mch bones + + eb[ 'MCH-eyes_parent' ].parent = None # eyes_parent will be parented to root + + # parent all mch tongue bones to the jaw master control bone + for bone in all_bones['mch']['tongue']: + eb[ bone ].parent = eb[ all_bones['ctrls']['jaw'][0] ] + + ## Parenting the control bones + + # parent teeth.B and tongue master controls to the jaw master control bone + for bone in [ 'teeth.B', 'tongue_master' ]: + eb[ bone ].parent = eb[ all_bones['ctrls']['jaw'][0] ] + + # eyes + eb[ 'eyes' ].parent = eb[ 'MCH-eyes_parent' ] + + eyes = [ + bone for bone in all_bones['ctrls']['eyes'] if 'eyes' not in bone + ][0:2] + + for eye in eyes: + eb[ eye ].parent = eb[ 'eyes' ] + + ## turbo: parent eye master bones to face + for eye_master in eyes[2:]: + eb[ eye_master ].parent = eb[ 'ORG-face' ] + + # Parent brow.b, eyes mch and lid tweaks and mch bones to masters + tweaks = [ + b for b in all_bones['tweaks']['all'] if 'lid' in b or 'brow.B' in b + ] + mch = all_bones['mch']['lids'] + \ + all_bones['mch']['eye.R'] + \ + all_bones['mch']['eye.L'] + + everyone = tweaks + mch + + left, right = self.symmetrical_split( everyone ) + + for l in left: + eb[ l ].parent = eb[ 'master_eye.L' ] + + for r in right: + eb[ r ].parent = eb[ 'master_eye.R' ] + + ## turbo: nose to mch jaw.004 + eb[ all_bones['ctrls']['nose'].pop() ].parent = eb['MCH-jaw_master.004'] + + ## Parenting the tweak bones + + # Jaw children (values) groups and their parents (keys) + groups = { + 'jaw_master' : [ + 'jaw', + 'jaw.R.001', + 'jaw.L.001', + 'chin.L', + 'chin.R', + 'chin', + 'tongue.003' + ], + 'MCH-jaw_master' : [ + 'lip.B' + ], + 'MCH-jaw_master.001' : [ + 'lip.B.L.001', + 'lip.B.R.001' + ], + 'MCH-jaw_master.002' : [ + 'lips.L', + 'lips.R', + 'cheek.B.L.001', + 'cheek.B.R.001' + ], + 'MCH-jaw_master.003' : [ + 'lip.T', + 'lip.T.L.001', + 'lip.T.R.001' + ], + 'MCH-jaw_master.004' : [ + 'cheek.T.L.001', + 'cheek.T.R.001' + ], + 'nose_master' : [ + 'nose.002', + 'nose.004', + 'nose.L.001', + 'nose.R.001' + ] + } + + for parent in list( groups.keys() ): + for bone in groups[parent]: + eb[ bone ].parent = eb[ parent ] + + # Remaining arbitrary relatioships for tweak bone parenting + eb[ 'chin.001' ].parent = eb[ 'chin' ] + eb[ 'chin.002' ].parent = eb[ 'lip.B' ] + eb[ 'nose.001' ].parent = eb[ 'nose.002' ] + eb[ 'nose.003' ].parent = eb[ 'nose.002' ] + eb[ 'nose.005' ].parent = eb[ 'lip.T' ] + eb[ 'tongue' ].parent = eb[ 'tongue_master' ] + eb[ 'tongue.001' ].parent = eb[ 'MCH-tongue.001' ] + eb[ 'tongue.002' ].parent = eb[ 'MCH-tongue.002' ] + + for bone in [ 'ear.L.002', 'ear.L.003', 'ear.L.004' ]: + eb[ bone ].parent = eb[ 'ear.L' ] + eb[ bone.replace( '.L', '.R' ) ].parent = eb[ 'ear.R' ] + + + def make_constraits( self, constraint_type, bone, subtarget, influence = 1 ): + org_bones = self.org_bones + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + owner_pb = pb[bone] + + if constraint_type == 'def_tweak': + + const = owner_pb.constraints.new( 'DAMPED_TRACK' ) + const.target = self.obj + const.subtarget = subtarget + + const = owner_pb.constraints.new( 'STRETCH_TO' ) + const.target = self.obj + const.subtarget = subtarget + + elif constraint_type == 'def_lids': + + const = owner_pb.constraints.new( 'DAMPED_TRACK' ) + const.target = self.obj + const.subtarget = subtarget + const.head_tail = 1.0 + + const = owner_pb.constraints.new( 'STRETCH_TO' ) + const.target = self.obj + const.subtarget = subtarget + const.head_tail = 1.0 + + elif constraint_type == 'mch_eyes': + + const = owner_pb.constraints.new( 'DAMPED_TRACK' ) + const.target = self.obj + const.subtarget = subtarget + + elif constraint_type == 'mch_eyes_lids_follow': + + const = owner_pb.constraints.new( 'COPY_LOCATION' ) + const.target = self.obj + const.subtarget = subtarget + const.head_tail = 1.0 + + elif constraint_type == 'mch_eyes_parent': + + const = owner_pb.constraints.new( 'COPY_TRANSFORMS' ) + const.target = self.obj + const.subtarget = subtarget + + elif constraint_type == 'mch_jaw_master': + + const = owner_pb.constraints.new( 'COPY_TRANSFORMS' ) + const.target = self.obj + const.subtarget = subtarget + const.influence = influence + + elif constraint_type == 'teeth': + + const = owner_pb.constraints.new( 'COPY_TRANSFORMS' ) + const.target = self.obj + const.subtarget = subtarget + const.influence = influence + + elif constraint_type == 'tweak_copyloc': + + const = owner_pb.constraints.new( 'COPY_LOCATION' ) + const.target = self.obj + const.subtarget = subtarget + const.influence = influence + const.use_offset = True + const.target_space = 'LOCAL' + const.owner_space = 'LOCAL' + + elif constraint_type == 'tweak_copy_rot_scl': + + const = owner_pb.constraints.new( 'COPY_ROTATION' ) + const.target = self.obj + const.subtarget = subtarget + const.use_offset = True + const.target_space = 'LOCAL' + const.owner_space = 'LOCAL' + + const = owner_pb.constraints.new( 'COPY_SCALE' ) + const.target = self.obj + const.subtarget = subtarget + const.use_offset = True + const.target_space = 'LOCAL' + const.owner_space = 'LOCAL' + + elif constraint_type == 'tweak_copyloc_inv': + + const = owner_pb.constraints.new( 'COPY_LOCATION' ) + const.target = self.obj + const.subtarget = subtarget + const.influence = influence + const.target_space = 'LOCAL' + const.owner_space = 'LOCAL' + const.use_offset = True + const.invert_x = True + const.invert_y = True + const.invert_z = True + + elif constraint_type == 'mch_tongue_copy_trans': + + const = owner_pb.constraints.new( 'COPY_TRANSFORMS' ) + const.target = self.obj + const.subtarget = subtarget + const.influence = influence + + + def constraints( self, all_bones ): + ## Def bone constraints + + def_specials = { + # 'bone' : 'target' + 'DEF-jaw' : 'chin', + 'DEF-chin.L' : 'lips.L', + 'DEF-jaw.L.001' : 'chin.L', + 'DEF-chin.R' : 'lips.R', + 'DEF-jaw.R.001' : 'chin.R', + 'DEF-brow.T.L.003' : 'nose', + 'DEF-ear.L.003' : 'ear.L.004', + 'DEF-ear.L.004' : 'ear.L', + 'DEF-ear.R.003' : 'ear.R.004', + 'DEF-ear.R.004' : 'ear.R', + 'DEF-lip.B.L.001' : 'lips.L', + 'DEF-lip.B.R.001' : 'lips.R', + 'DEF-cheek.B.L.001' : 'brow.T.L', + 'DEF-cheek.B.R.001' : 'brow.T.R', + 'DEF-lip.T.L.001' : 'lips.L', + 'DEF-lip.T.R.001' : 'lips.R', + 'DEF-cheek.T.L.001' : 'nose.L', + 'DEF-nose.L.001' : 'nose.002', + 'DEF-cheek.T.R.001' : 'nose.R', + 'DEF-nose.R.001' : 'nose.002', + 'DEF-forehead.L' : 'brow.T.L.003', + 'DEF-forehead.L.001' : 'brow.T.L.002', + 'DEF-forehead.L.002' : 'brow.T.L.001', + 'DEF-temple.L' : 'jaw.L', + 'DEF-brow.T.R.003' : 'nose', + 'DEF-forehead.R' : 'brow.T.R.003', + 'DEF-forehead.R.001' : 'brow.T.R.002', + 'DEF-forehead.R.002' : 'brow.T.R.001', + 'DEF-temple.R' : 'jaw.R' + } + + pattern = r'^DEF-(\w+\.?\w?\.?\w?)(\.?)(\d*?)(\d?)$' + + for bone in [ bone for bone in all_bones['deform']['all'] if 'lid' not in bone ]: + if bone in list( def_specials.keys() ): + self.make_constraits('def_tweak', bone, def_specials[bone] ) + else: + matches = re.match( pattern, bone ).groups() + if len( matches ) > 1 and matches[-1]: + num = int( matches[-1] ) + 1 + str_list = list( matches )[:-1] + [ str( num ) ] + tweak = "".join( str_list ) + else: + tweak = "".join( matches ) + ".001" + self.make_constraits('def_tweak', bone, tweak ) + + def_lids = sorted( [ bone for bone in all_bones['deform']['all'] if 'lid' in bone ] ) + mch_lids = sorted( [ bone for bone in all_bones['mch']['lids'] ] ) + + def_lidsL, def_lidsR = self.symmetrical_split( def_lids ) + mch_lidsL, mch_lidsR = self.symmetrical_split( mch_lids ) + + # Take the last mch_lid bone and place it at the end + mch_lidsL = mch_lidsL[1:] + [ mch_lidsL[0] ] + mch_lidsR = mch_lidsR[1:] + [ mch_lidsR[0] ] + + for boneL, boneR, mchL, mchR in zip( def_lidsL, def_lidsR, mch_lidsL, mch_lidsR ): + self.make_constraits('def_lids', boneL, mchL ) + self.make_constraits('def_lids', boneR, mchR ) + + ## MCH constraints + + # mch lids constraints + for bone in all_bones['mch']['lids']: + tweak = bone[4:] # remove "MCH-" from bone name + self.make_constraits('mch_eyes', bone, tweak ) + + # mch eyes constraints + for bone in [ 'MCH-eye.L', 'MCH-eye.R' ]: + ctrl = bone[4:] # remove "MCH-" from bone name + self.make_constraits('mch_eyes', bone, ctrl ) + + for bone in [ 'MCH-eye.L.001', 'MCH-eye.R.001' ]: + target = bone[:-4] # remove number from the end of the name + self.make_constraits('mch_eyes_lids_follow', bone, target ) + + # mch eyes parent constraints + self.make_constraits('mch_eyes_parent', 'MCH-eyes_parent', 'ORG-face' ) + + ## Jaw constraints + + # jaw master mch bones + self.make_constraits( 'mch_jaw_master', 'MCH-mouth_lock', 'jaw_master', 0.20 ) + self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master', 'jaw_master', 1.00 ) + self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.001', 'jaw_master', 0.75 ) + self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.002', 'jaw_master', 0.35 ) + self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.003', 'jaw_master', 0.10 ) + self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.004', 'jaw_master', 0.025 ) + + self.make_constraits( 'teeth', 'ORG-teeth.T', 'teeth.T', 1.00 ) + self.make_constraits( 'teeth', 'ORG-teeth.B', 'teeth.B', 1.00 ) + + for bone in all_bones['mch']['jaw'][1:-1]: + self.make_constraits( 'mch_jaw_master', bone, 'MCH-mouth_lock' ) + + ## Tweak bones constraints + + # copy location constraints for tweak bones of both sides + tweak_copyloc_L = { + 'brow.T.L.002' : [ [ 'brow.T.L.001', 'brow.T.L.003' ], [ 0.5, 0.5 ] ], + 'ear.L.003' : [ [ 'ear.L.004', 'ear.L.002' ], [ 0.5, 0.5 ] ], + 'brow.B.L.001' : [ [ 'brow.B.L.002' ], [ 0.6 ] ], + 'brow.B.L.003' : [ [ 'brow.B.L.002' ], [ 0.6 ] ], + 'brow.B.L.002' : [ [ 'lid.T.L.001', ], [ 0.25 ] ], + 'brow.B.L.002' : [ [ 'brow.T.L.002', ], [ 0.25 ] ], + 'lid.T.L.001' : [ [ 'lid.T.L.002' ], [ 0.6 ] ], + 'lid.T.L.003' : [ [ 'lid.T.L.002', ], [ 0.6 ] ], + 'lid.T.L.002' : [ [ 'MCH-eye.L.001', ], [ 0.5 ] ], + 'lid.B.L.001' : [ [ 'lid.B.L.002', ], [ 0.6 ] ], + 'lid.B.L.003' : [ [ 'lid.B.L.002', ], [ 0.6 ] ], + 'lid.B.L.002' : [ [ 'MCH-eye.L.001', 'cheek.T.L.001' ], [ 0.5, 0.1 ] ], + 'cheek.T.L.001' : [ [ 'cheek.B.L.001', ], [ 0.5 ] ], + 'nose.L' : [ [ 'nose.L.001', ], [ 0.25 ] ], + 'nose.L.001' : [ [ 'lip.T.L.001', ], [ 0.2 ] ], + 'cheek.B.L.001' : [ [ 'lips.L', ], [ 0.5 ] ], + 'lip.T.L.001' : [ [ 'lips.L', 'lip.T' ], [ 0.25, 0.5 ] ], + 'lip.B.L.001' : [ [ 'lips.L', 'lip.B' ], [ 0.25, 0.5 ] ] + } + + for owner in list( tweak_copyloc_L.keys() ): + + targets, influences = tweak_copyloc_L[owner] + for target, influence in zip( targets, influences ): + + # Left side constraints + self.make_constraits( 'tweak_copyloc', owner, target, influence ) + + # create constraints for the right side too + ownerR = owner.replace( '.L', '.R' ) + targetR = target.replace( '.L', '.R' ) + self.make_constraits( 'tweak_copyloc', ownerR, targetR, influence ) + + # copy rotation & scale constraints for tweak bones of both sides + tweak_copy_rot_scl_L = { + 'lip.T.L.001' : 'lip.T', + 'lip.B.L.001' : 'lip.B' + } + + for owner in list( tweak_copy_rot_scl_L.keys() ): + target = tweak_copy_rot_scl_L[owner] + influence = tweak_copy_rot_scl_L[owner] + self.make_constraits( 'tweak_copy_rot_scl', owner, target ) + + # create constraints for the right side too + owner = owner.replace( '.L', '.R' ) + self.make_constraits( 'tweak_copy_rot_scl', owner, target ) + + # inverted tweak bones constraints + tweak_nose = { + 'nose.001' : [ 'nose.002', 0.35 ], + 'nose.003' : [ 'nose.002', 0.5 ], + 'nose.005' : [ 'lip.T', 0.5 ], + 'chin.002' : [ 'lip.B', 0.5 ] + } + + for owner in list( tweak_nose.keys() ): + target = tweak_nose[owner][0] + influence = tweak_nose[owner][1] + self.make_constraits( 'tweak_copyloc_inv', owner, target, influence ) + + # MCH tongue constraints + divider = len( all_bones['mch']['tongue'] ) + 1 + factor = len( all_bones['mch']['tongue'] ) + + for owner in all_bones['mch']['tongue']: + self.make_constraits( 'mch_tongue_copy_trans', owner, 'tongue_master', ( 1 / divider ) * factor ) + factor -= 1 + + + def drivers_and_props( self, all_bones ): + + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + jaw_ctrl = all_bones['ctrls']['jaw'][0] + eyes_ctrl = all_bones['ctrls']['eyes'][2] + + jaw_prop = 'mouth_lock' + eyes_prop = 'eyes_follow' + + for bone, prop_name in zip( [ jaw_ctrl, eyes_ctrl ], [ jaw_prop, eyes_prop ] ): + if bone == jaw_ctrl: + pb[ bone ][ prop_name ] = 0.0 + else: + pb[ bone ][ prop_name ] = 1.0 + + prop = rna_idprop_ui_prop_get( pb[ bone ], prop_name ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = prop_name + + # Jaw drivers + mch_jaws = all_bones['mch']['jaw'][1:-1] + + for bone in mch_jaws: + drv = pb[ bone ].constraints[1].driver_add("influence").driver + drv.type='SUM' + + var = drv.variables.new() + var.name = jaw_prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = pb[ jaw_ctrl ].path_from_id() + '['+ '"' + jaw_prop + '"' + ']' + + + # Eyes driver + mch_eyes_parent = all_bones['mch']['eyes_parent'][0] + + drv = pb[ mch_eyes_parent ].constraints[0].driver_add("influence").driver + drv.type='SUM' + + var = drv.variables.new() + var.name = eyes_prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = pb[ eyes_ctrl ].path_from_id() + '['+ '"' + eyes_prop + '"' + ']' + + return jaw_prop, eyes_prop + + def create_bones(self): + org_bones = self.org_bones + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Clear parents for org bones + for bone in [ bone for bone in org_bones if 'face' not in bone ]: + eb[bone].use_connect = False + eb[bone].parent = None + + all_bones = {} + + def_names = self.create_deformation() + ctrls, tweak_unique = self.all_controls() + mchs = self.create_mch( + ctrls['ctrls']['jaw'][0], + ctrls['ctrls']['tongue'][0] + ) + return { + 'deform' : def_names, + 'ctrls' : ctrls['ctrls'], + 'tweaks' : ctrls['tweaks'], + 'mch' : mchs + }, tweak_unique + + + def generate(self): + + all_bones, tweak_unique = self.create_bones() + self.parent_bones( all_bones, tweak_unique ) + self.constraints( all_bones ) + jaw_prop, eyes_prop = self.drivers_and_props( all_bones ) + + + # Create UI + all_controls = [] + all_controls += [ bone for bone in [ bgroup for bgroup in [ all_bones['ctrls'][group] for group in list( all_bones['ctrls'].keys() ) ] ] ] + all_controls += [ bone for bone in [ bgroup for bgroup in [ all_bones['tweaks'][group] for group in list( all_bones['tweaks'].keys() ) ] ] ] + + all_ctrls = [] + for group in all_controls: + for bone in group: + all_ctrls.append( bone ) + + controls_string = ", ".join(["'" + x + "'" for x in all_ctrls]) + return [ script % ( + controls_string, + all_bones['ctrls']['jaw'][0], + all_bones['ctrls']['eyes'][2], + jaw_prop, + eyes_prop ) + ] + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + + #Setting up extra layers for the tweak bones + params.primary_layers_extra = bpy.props.BoolProperty( + name = "primary_layers_extra", + default = True, + description = "" + ) + params.primary_layers = bpy.props.BoolVectorProperty( + size = 32, + description = "Layers for the 1st tweak controls to be on", + default = tuple( [ i == 1 for i in range(0, 32) ] ) + ) + params.secondary_layers_extra = bpy.props.BoolProperty( + name = "secondary_layers_extra", + default = True, + description = "" + ) + params.secondary_layers = bpy.props.BoolVectorProperty( + size = 32, + description = "Layers for the 2nd 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.""" + layers = ["primary_layers", "secondary_layers"] + + for layer in layers: + r = layout.row() + r.prop( params, layer + "_extra" ) + r.active = getattr( params, layer + "_extra" ) + + col = r.column(align=True) + row = col.row(align=True) + for i in range(8): + row.prop(params, layer, index=i, toggle=True, text="") + + row = col.row(align=True) + for i in range(16,24): + row.prop(params, layer, index=i, toggle=True, text="") + + col = r.column(align=True) + row = col.row(align=True) + + for i in range(8,16): + row.prop(params, layer, index=i, toggle=True, text="") + + row = col.row(align=True) + for i in range(24,32): + row.prop(params, layer, 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('face') + bone.head[:] = -0.0000, -0.0013, 0.0437 + bone.tail[:] = -0.0000, -0.0013, 0.1048 + bone.roll = 0.0000 + bone.use_connect = False + bones['face'] = bone.name + bone = arm.edit_bones.new('nose') + bone.head[:] = 0.0000, -0.0905, 0.1125 + bone.tail[:] = 0.0000, -0.1105, 0.0864 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['nose'] = bone.name + bone = arm.edit_bones.new('lip.T.L') + bone.head[:] = 0.0000, -0.1022, 0.0563 + bone.tail[:] = 0.0131, -0.0986, 0.0567 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.L'] = bone.name + bone = arm.edit_bones.new('lip.B.L') + bone.head[:] = 0.0000, -0.0993, 0.0455 + bone.tail[:] = 0.0124, -0.0938, 0.0488 + bone.roll = -0.0789 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.L'] = bone.name + bone = arm.edit_bones.new('jaw') + bone.head[:] = 0.0000, -0.0389, 0.0222 + bone.tail[:] = 0.0000, -0.0923, 0.0044 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['jaw'] = bone.name + bone = arm.edit_bones.new('ear.L') + bone.head[:] = 0.0616, -0.0083, 0.0886 + bone.tail[:] = 0.0663, -0.0101, 0.1151 + bone.roll = -0.0324 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.L'] = bone.name + bone = arm.edit_bones.new('ear.R') + bone.head[:] = -0.0616, -0.0083, 0.0886 + bone.tail[:] = -0.0663, -0.0101, 0.1151 + bone.roll = 0.0324 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['ear.R'] = bone.name + bone = arm.edit_bones.new('lip.T.R') + bone.head[:] = -0.0000, -0.1022, 0.0563 + bone.tail[:] = -0.0131, -0.0986, 0.0567 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.T.R'] = bone.name + bone = arm.edit_bones.new('lip.B.R') + bone.head[:] = -0.0000, -0.0993, 0.0455 + bone.tail[:] = -0.0124, -0.0938, 0.0488 + bone.roll = 0.0789 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lip.B.R'] = bone.name + bone = arm.edit_bones.new('brow.B.L') + bone.head[:] = 0.0530, -0.0705, 0.1153 + bone.tail[:] = 0.0472, -0.0780, 0.1192 + bone.roll = 0.0412 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.L'] = bone.name + bone = arm.edit_bones.new('lid.T.L') + bone.head[:] = 0.0515, -0.0692, 0.1104 + bone.tail[:] = 0.0474, -0.0785, 0.1136 + bone.roll = 0.1166 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.L'] = bone.name + bone = arm.edit_bones.new('brow.B.R') + bone.head[:] = -0.0530, -0.0705, 0.1153 + bone.tail[:] = -0.0472, -0.0780, 0.1192 + bone.roll = -0.0412 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['brow.B.R'] = bone.name + bone = arm.edit_bones.new('lid.T.R') + bone.head[:] = -0.0515, -0.0692, 0.1104 + bone.tail[:] = -0.0474, -0.0785, 0.1136 + bone.roll = -0.1166 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['lid.T.R'] = bone.name + bone = arm.edit_bones.new('forehead.L') + bone.head[:] = 0.0113, -0.0764, 0.1611 + bone.tail[:] = 0.0144, -0.0912, 0.1236 + bone.roll = 1.4313 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.L'] = bone.name + bone = arm.edit_bones.new('forehead.R') + bone.head[:] = -0.0113, -0.0764, 0.1611 + bone.tail[:] = -0.0144, -0.0912, 0.1236 + bone.roll = -1.4313 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['forehead.R'] = bone.name + bone = arm.edit_bones.new('eye.L') + bone.head[:] = 0.0360, -0.0686, 0.1107 + bone.tail[:] = 0.0360, -0.0848, 0.1107 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.L'] = bone.name + bone = arm.edit_bones.new('eye.R') + bone.head[:] = -0.0360, -0.0686, 0.1107 + bone.tail[:] = -0.0360, -0.0848, 0.1107 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['eye.R'] = bone.name + bone = arm.edit_bones.new('cheek.T.L') + bone.head[:] = 0.0568, -0.0506, 0.1052 + bone.tail[:] = 0.0379, -0.0834, 0.0816 + bone.roll = -0.0096 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.L'] = bone.name + bone = arm.edit_bones.new('cheek.T.R') + bone.head[:] = -0.0568, -0.0506, 0.1052 + bone.tail[:] = -0.0379, -0.0834, 0.0816 + bone.roll = 0.0096 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['cheek.T.R'] = bone.name + bone = arm.edit_bones.new('teeth.T') + bone.head[:] = 0.0000, -0.0927, 0.0613 + bone.tail[:] = 0.0000, -0.0621, 0.0613 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.T'] = bone.name + bone = arm.edit_bones.new('teeth.B') + bone.head[:] = 0.0000, -0.0881, 0.0397 + bone.tail[:] = 0.0000, -0.0575, 0.0397 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['teeth.B'] = bone.name + bone = arm.edit_bones.new('tongue') + bone.head[:] = 0.0000, -0.0781, 0.0493 + bone.tail[:] = 0.0000, -0.0620, 0.0567 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['tongue'] = bone.name + bone = arm.edit_bones.new('nose.001') + bone.head[:] = 0.0000, -0.1105, 0.0864 + bone.tail[:] = 0.0000, -0.1193, 0.0771 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose']] + bones['nose.001'] = bone.name + bone = arm.edit_bones.new('lip.T.L.001') + bone.head[:] = 0.0131, -0.0986, 0.0567 + bone.tail[:] = 0.0236, -0.0877, 0.0519 + bone.roll = 0.0236 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.L']] + bones['lip.T.L.001'] = bone.name + bone = arm.edit_bones.new('lip.B.L.001') + bone.head[:] = 0.0124, -0.0938, 0.0488 + bone.tail[:] = 0.0236, -0.0877, 0.0519 + bone.roll = 0.0731 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.L']] + bones['lip.B.L.001'] = bone.name + bone = arm.edit_bones.new('chin') + bone.head[:] = 0.0000, -0.0923, 0.0044 + bone.tail[:] = 0.0000, -0.0921, 0.0158 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw']] + bones['chin'] = bone.name + bone = arm.edit_bones.new('ear.L.001') + bone.head[:] = 0.0663, -0.0101, 0.1151 + bone.tail[:] = 0.0804, 0.0065, 0.1189 + bone.roll = 0.0656 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L']] + bones['ear.L.001'] = bone.name + bone = arm.edit_bones.new('ear.R.001') + bone.head[:] = -0.0663, -0.0101, 0.1151 + bone.tail[:] = -0.0804, 0.0065, 0.1189 + bone.roll = -0.0656 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R']] + bones['ear.R.001'] = bone.name + bone = arm.edit_bones.new('lip.T.R.001') + bone.head[:] = -0.0131, -0.0986, 0.0567 + bone.tail[:] = -0.0236, -0.0877, 0.0519 + bone.roll = -0.0236 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.T.R']] + bones['lip.T.R.001'] = bone.name + bone = arm.edit_bones.new('lip.B.R.001') + bone.head[:] = -0.0124, -0.0938, 0.0488 + bone.tail[:] = -0.0236, -0.0877, 0.0519 + bone.roll = -0.0731 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lip.B.R']] + bones['lip.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.B.L.001') + bone.head[:] = 0.0472, -0.0780, 0.1192 + bone.tail[:] = 0.0387, -0.0832, 0.1202 + bone.roll = 0.0192 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L']] + bones['brow.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.T.L.001') + bone.head[:] = 0.0474, -0.0785, 0.1136 + bone.tail[:] = 0.0394, -0.0838, 0.1147 + bone.roll = 0.0791 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L']] + bones['lid.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.B.R.001') + bone.head[:] = -0.0472, -0.0780, 0.1192 + bone.tail[:] = -0.0387, -0.0832, 0.1202 + bone.roll = -0.0192 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R']] + bones['brow.B.R.001'] = bone.name + bone = arm.edit_bones.new('lid.T.R.001') + bone.head[:] = -0.0474, -0.0785, 0.1136 + bone.tail[:] = -0.0394, -0.0838, 0.1147 + bone.roll = -0.0791 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R']] + bones['lid.T.R.001'] = bone.name + bone = arm.edit_bones.new('forehead.L.001') + bone.head[:] = 0.0321, -0.0663, 0.1646 + bone.tail[:] = 0.0394, -0.0828, 0.1310 + bone.roll = 0.9928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L']] + bones['forehead.L.001'] = bone.name + bone = arm.edit_bones.new('forehead.R.001') + bone.head[:] = -0.0321, -0.0663, 0.1646 + bone.tail[:] = -0.0394, -0.0828, 0.1310 + bone.roll = -0.9928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R']] + bones['forehead.R.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.L.001') + bone.head[:] = 0.0379, -0.0834, 0.0816 + bone.tail[:] = 0.0093, -0.0846, 0.1002 + bone.roll = 0.0320 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L']] + bones['cheek.T.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.T.R.001') + bone.head[:] = -0.0379, -0.0834, 0.0816 + bone.tail[:] = -0.0093, -0.0846, 0.1002 + bone.roll = -0.0320 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R']] + bones['cheek.T.R.001'] = bone.name + bone = arm.edit_bones.new('tongue.001') + bone.head[:] = 0.0000, -0.0620, 0.0567 + bone.tail[:] = 0.0000, -0.0406, 0.0584 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue']] + bones['tongue.001'] = bone.name + bone = arm.edit_bones.new('nose.002') + bone.head[:] = 0.0000, -0.1193, 0.0771 + bone.tail[:] = 0.0000, -0.1118, 0.0739 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.001']] + bones['nose.002'] = bone.name + bone = arm.edit_bones.new('chin.001') + bone.head[:] = 0.0000, -0.0921, 0.0158 + bone.tail[:] = 0.0000, -0.0914, 0.0404 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin']] + bones['chin.001'] = bone.name + bone = arm.edit_bones.new('ear.L.002') + bone.head[:] = 0.0804, 0.0065, 0.1189 + bone.tail[:] = 0.0808, 0.0056, 0.0935 + bone.roll = -0.0265 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.001']] + bones['ear.L.002'] = bone.name + bone = arm.edit_bones.new('ear.R.002') + bone.head[:] = -0.0804, 0.0065, 0.1189 + bone.tail[:] = -0.0808, 0.0056, 0.0935 + bone.roll = 0.0265 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.001']] + bones['ear.R.002'] = bone.name + bone = arm.edit_bones.new('brow.B.L.002') + bone.head[:] = 0.0387, -0.0832, 0.1202 + bone.tail[:] = 0.0295, -0.0826, 0.1179 + bone.roll = -0.0278 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.001']] + bones['brow.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.T.L.002') + bone.head[:] = 0.0394, -0.0838, 0.1147 + bone.tail[:] = 0.0317, -0.0832, 0.1131 + bone.roll = -0.0356 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.001']] + bones['lid.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.B.R.002') + bone.head[:] = -0.0387, -0.0832, 0.1202 + bone.tail[:] = -0.0295, -0.0826, 0.1179 + bone.roll = 0.0278 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.001']] + bones['brow.B.R.002'] = bone.name + bone = arm.edit_bones.new('lid.T.R.002') + bone.head[:] = -0.0394, -0.0838, 0.1147 + bone.tail[:] = -0.0317, -0.0832, 0.1131 + bone.roll = 0.0356 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.001']] + bones['lid.T.R.002'] = bone.name + bone = arm.edit_bones.new('forehead.L.002') + bone.head[:] = 0.0482, -0.0506, 0.1620 + bone.tail[:] = 0.0556, -0.0689, 0.1249 + bone.roll = 0.4509 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.001']] + bones['forehead.L.002'] = bone.name + bone = arm.edit_bones.new('forehead.R.002') + bone.head[:] = -0.0482, -0.0506, 0.1620 + bone.tail[:] = -0.0556, -0.0689, 0.1249 + bone.roll = -0.4509 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.001']] + bones['forehead.R.002'] = bone.name + bone = arm.edit_bones.new('nose.L') + bone.head[:] = 0.0093, -0.0846, 0.1002 + bone.tail[:] = 0.0118, -0.0966, 0.0757 + bone.roll = -0.0909 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.L.001']] + bones['nose.L'] = bone.name + bone = arm.edit_bones.new('nose.R') + bone.head[:] = -0.0093, -0.0846, 0.1002 + bone.tail[:] = -0.0118, -0.0966, 0.0757 + bone.roll = 0.0909 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.T.R.001']] + bones['nose.R'] = bone.name + bone = arm.edit_bones.new('tongue.002') + bone.head[:] = 0.0000, -0.0406, 0.0584 + bone.tail[:] = 0.0000, -0.0178, 0.0464 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tongue.001']] + bones['tongue.002'] = bone.name + bone = arm.edit_bones.new('nose.003') + bone.head[:] = 0.0000, -0.1118, 0.0739 + bone.tail[:] = 0.0000, -0.1019, 0.0733 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.002']] + bones['nose.003'] = bone.name + bone = arm.edit_bones.new('ear.L.003') + bone.head[:] = 0.0808, 0.0056, 0.0935 + bone.tail[:] = 0.0677, -0.0109, 0.0752 + bone.roll = 0.3033 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.002']] + bones['ear.L.003'] = bone.name + bone = arm.edit_bones.new('ear.R.003') + bone.head[:] = -0.0808, 0.0056, 0.0935 + bone.tail[:] = -0.0677, -0.0109, 0.0752 + bone.roll = -0.3033 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.002']] + bones['ear.R.003'] = bone.name + bone = arm.edit_bones.new('brow.B.L.003') + bone.head[:] = 0.0295, -0.0826, 0.1179 + bone.tail[:] = 0.0201, -0.0812, 0.1095 + bone.roll = 0.0417 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.L.002']] + bones['brow.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.T.L.003') + bone.head[:] = 0.0317, -0.0832, 0.1131 + bone.tail[:] = 0.0237, -0.0826, 0.1058 + bone.roll = 0.0245 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.002']] + bones['lid.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.B.R.003') + bone.head[:] = -0.0295, -0.0826, 0.1179 + bone.tail[:] = -0.0201, -0.0812, 0.1095 + bone.roll = -0.0417 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.B.R.002']] + bones['brow.B.R.003'] = bone.name + bone = arm.edit_bones.new('lid.T.R.003') + bone.head[:] = -0.0317, -0.0832, 0.1131 + bone.tail[:] = -0.0237, -0.0826, 0.1058 + bone.roll = -0.0245 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.002']] + bones['lid.T.R.003'] = bone.name + bone = arm.edit_bones.new('temple.L') + bone.head[:] = 0.0585, -0.0276, 0.1490 + bone.tail[:] = 0.0607, -0.0295, 0.0962 + bone.roll = -0.0650 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.L.002']] + bones['temple.L'] = bone.name + bone = arm.edit_bones.new('temple.R') + bone.head[:] = -0.0585, -0.0276, 0.1490 + bone.tail[:] = -0.0607, -0.0295, 0.0962 + bone.roll = 0.0650 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['forehead.R.002']] + bones['temple.R'] = bone.name + bone = arm.edit_bones.new('nose.L.001') + bone.head[:] = 0.0118, -0.0966, 0.0757 + bone.tail[:] = 0.0000, -0.1193, 0.0771 + bone.roll = 0.1070 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.L']] + bones['nose.L.001'] = bone.name + bone = arm.edit_bones.new('nose.R.001') + bone.head[:] = -0.0118, -0.0966, 0.0757 + bone.tail[:] = -0.0000, -0.1193, 0.0771 + bone.roll = -0.1070 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.R']] + bones['nose.R.001'] = bone.name + bone = arm.edit_bones.new('nose.004') + bone.head[:] = 0.0000, -0.1019, 0.0733 + bone.tail[:] = 0.0000, -0.1014, 0.0633 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['nose.003']] + bones['nose.004'] = bone.name + bone = arm.edit_bones.new('ear.L.004') + bone.head[:] = 0.0677, -0.0109, 0.0752 + bone.tail[:] = 0.0616, -0.0083, 0.0886 + bone.roll = 0.1518 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.L.003']] + bones['ear.L.004'] = bone.name + bone = arm.edit_bones.new('ear.R.004') + bone.head[:] = -0.0677, -0.0109, 0.0752 + bone.tail[:] = -0.0616, -0.0083, 0.0886 + bone.roll = -0.1518 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['ear.R.003']] + bones['ear.R.004'] = bone.name + bone = arm.edit_bones.new('lid.B.L') + bone.head[:] = 0.0237, -0.0826, 0.1058 + bone.tail[:] = 0.0319, -0.0831, 0.1050 + bone.roll = -0.1108 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.L.003']] + bones['lid.B.L'] = bone.name + bone = arm.edit_bones.new('lid.B.R') + bone.head[:] = -0.0237, -0.0826, 0.1058 + bone.tail[:] = -0.0319, -0.0831, 0.1050 + bone.roll = 0.1108 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.T.R.003']] + bones['lid.B.R'] = bone.name + bone = arm.edit_bones.new('jaw.L') + bone.head[:] = 0.0607, -0.0295, 0.0962 + bone.tail[:] = 0.0451, -0.0338, 0.0533 + bone.roll = 0.0871 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.L']] + bones['jaw.L'] = bone.name + bone = arm.edit_bones.new('jaw.R') + bone.head[:] = -0.0607, -0.0295, 0.0962 + bone.tail[:] = -0.0451, -0.0338, 0.0533 + bone.roll = -0.0871 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['temple.R']] + bones['jaw.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.001') + bone.head[:] = 0.0319, -0.0831, 0.1050 + bone.tail[:] = 0.0389, -0.0826, 0.1050 + bone.roll = -0.0207 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L']] + bones['lid.B.L.001'] = bone.name + bone = arm.edit_bones.new('lid.B.R.001') + bone.head[:] = -0.0319, -0.0831, 0.1050 + bone.tail[:] = -0.0389, -0.0826, 0.1050 + bone.roll = 0.0207 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R']] + bones['lid.B.R.001'] = bone.name + bone = arm.edit_bones.new('jaw.L.001') + bone.head[:] = 0.0451, -0.0338, 0.0533 + bone.tail[:] = 0.0166, -0.0758, 0.0187 + bone.roll = 0.0458 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L']] + bones['jaw.L.001'] = bone.name + bone = arm.edit_bones.new('jaw.R.001') + bone.head[:] = -0.0451, -0.0338, 0.0533 + bone.tail[:] = -0.0166, -0.0758, 0.0187 + bone.roll = -0.0458 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R']] + bones['jaw.R.001'] = bone.name + bone = arm.edit_bones.new('lid.B.L.002') + bone.head[:] = 0.0389, -0.0826, 0.1050 + bone.tail[:] = 0.0472, -0.0781, 0.1068 + bone.roll = 0.0229 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.001']] + bones['lid.B.L.002'] = bone.name + bone = arm.edit_bones.new('lid.B.R.002') + bone.head[:] = -0.0389, -0.0826, 0.1050 + bone.tail[:] = -0.0472, -0.0781, 0.1068 + bone.roll = -0.0229 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.001']] + bones['lid.B.R.002'] = bone.name + bone = arm.edit_bones.new('chin.L') + bone.head[:] = 0.0166, -0.0758, 0.0187 + bone.tail[:] = 0.0236, -0.0877, 0.0519 + bone.roll = 0.1513 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.L.001']] + bones['chin.L'] = bone.name + bone = arm.edit_bones.new('chin.R') + bone.head[:] = -0.0166, -0.0758, 0.0187 + bone.tail[:] = -0.0236, -0.0877, 0.0519 + bone.roll = -0.1513 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['jaw.R.001']] + bones['chin.R'] = bone.name + bone = arm.edit_bones.new('lid.B.L.003') + bone.head[:] = 0.0472, -0.0781, 0.1068 + bone.tail[:] = 0.0515, -0.0692, 0.1104 + bone.roll = -0.0147 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.L.002']] + bones['lid.B.L.003'] = bone.name + bone = arm.edit_bones.new('lid.B.R.003') + bone.head[:] = -0.0472, -0.0781, 0.1068 + bone.tail[:] = -0.0515, -0.0692, 0.1104 + bone.roll = 0.0147 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['lid.B.R.002']] + bones['lid.B.R.003'] = bone.name + bone = arm.edit_bones.new('cheek.B.L') + bone.head[:] = 0.0236, -0.0877, 0.0519 + bone.tail[:] = 0.0493, -0.0691, 0.0632 + bone.roll = 0.0015 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.L']] + bones['cheek.B.L'] = bone.name + bone = arm.edit_bones.new('cheek.B.R') + bone.head[:] = -0.0236, -0.0877, 0.0519 + bone.tail[:] = -0.0493, -0.0691, 0.0632 + bone.roll = -0.0015 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['chin.R']] + bones['cheek.B.R'] = bone.name + bone = arm.edit_bones.new('cheek.B.L.001') + bone.head[:] = 0.0493, -0.0691, 0.0632 + bone.tail[:] = 0.0568, -0.0506, 0.1052 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L']] + bones['cheek.B.L.001'] = bone.name + bone = arm.edit_bones.new('cheek.B.R.001') + bone.head[:] = -0.0493, -0.0691, 0.0632 + bone.tail[:] = -0.0568, -0.0506, 0.1052 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R']] + bones['cheek.B.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L') + bone.head[:] = 0.0568, -0.0506, 0.1052 + bone.tail[:] = 0.0556, -0.0689, 0.1249 + bone.roll = 0.1990 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.L.001']] + bones['brow.T.L'] = bone.name + bone = arm.edit_bones.new('brow.T.R') + bone.head[:] = -0.0568, -0.0506, 0.1052 + bone.tail[:] = -0.0556, -0.0689, 0.1249 + bone.roll = -0.1990 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['cheek.B.R.001']] + bones['brow.T.R'] = bone.name + bone = arm.edit_bones.new('brow.T.L.001') + bone.head[:] = 0.0556, -0.0689, 0.1249 + bone.tail[:] = 0.0394, -0.0828, 0.1310 + bone.roll = 0.2372 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L']] + bones['brow.T.L.001'] = bone.name + bone = arm.edit_bones.new('brow.T.R.001') + bone.head[:] = -0.0556, -0.0689, 0.1249 + bone.tail[:] = -0.0394, -0.0828, 0.1310 + bone.roll = -0.2372 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R']] + bones['brow.T.R.001'] = bone.name + bone = arm.edit_bones.new('brow.T.L.002') + bone.head[:] = 0.0394, -0.0828, 0.1310 + bone.tail[:] = 0.0144, -0.0912, 0.1236 + bone.roll = 0.0724 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.001']] + bones['brow.T.L.002'] = bone.name + bone = arm.edit_bones.new('brow.T.R.002') + bone.head[:] = -0.0394, -0.0828, 0.1310 + bone.tail[:] = -0.0144, -0.0912, 0.1236 + bone.roll = -0.0724 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.001']] + bones['brow.T.R.002'] = bone.name + bone = arm.edit_bones.new('brow.T.L.003') + bone.head[:] = 0.0144, -0.0912, 0.1236 + bone.tail[:] = 0.0003, -0.0905, 0.1125 + bone.roll = -0.0423 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.L.002']] + bones['brow.T.L.003'] = bone.name + bone = arm.edit_bones.new('brow.T.R.003') + bone.head[:] = -0.0144, -0.0912, 0.1236 + bone.tail[:] = -0.0003, -0.0905, 0.1125 + bone.roll = 0.0423 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['brow.T.R.002']] + bones['brow.T.R.003'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['face']] + pbone.rigify_type = 'pitchipoy.super_face' + 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 = obj.pose.bones[bones['nose']] + 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 = obj.pose.bones[bones['lip.T.L']] + 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 = obj.pose.bones[bones['lip.B.L']] + 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 = obj.pose.bones[bones['jaw']] + 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 = obj.pose.bones[bones['ear.L']] + 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 = obj.pose.bones[bones['ear.R']] + 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 = obj.pose.bones[bones['lip.T.R']] + 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 = obj.pose.bones[bones['lip.B.R']] + 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 = obj.pose.bones[bones['brow.B.L']] + 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 = obj.pose.bones[bones['lid.T.L']] + 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 = obj.pose.bones[bones['brow.B.R']] + 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 = obj.pose.bones[bones['lid.T.R']] + 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 = obj.pose.bones[bones['forehead.L']] + 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 = obj.pose.bones[bones['forehead.R']] + 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 = obj.pose.bones[bones['eye.L']] + 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 = obj.pose.bones[bones['eye.R']] + 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 = obj.pose.bones[bones['cheek.T.L']] + 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 = obj.pose.bones[bones['cheek.T.R']] + 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 = obj.pose.bones[bones['teeth.T']] + 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 = obj.pose.bones[bones['teeth.B']] + 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 = obj.pose.bones[bones['tongue']] + 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 = obj.pose.bones[bones['nose.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 = obj.pose.bones[bones['lip.T.L.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 = obj.pose.bones[bones['lip.B.L.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 = obj.pose.bones[bones['chin']] + 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 = obj.pose.bones[bones['ear.L.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 = obj.pose.bones[bones['ear.R.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 = obj.pose.bones[bones['lip.T.R.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 = obj.pose.bones[bones['lip.B.R.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 = obj.pose.bones[bones['brow.B.L.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 = obj.pose.bones[bones['lid.T.L.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 = obj.pose.bones[bones['brow.B.R.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 = obj.pose.bones[bones['lid.T.R.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 = obj.pose.bones[bones['forehead.L.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 = obj.pose.bones[bones['forehead.R.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 = obj.pose.bones[bones['cheek.T.L.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 = obj.pose.bones[bones['cheek.T.R.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 = obj.pose.bones[bones['tongue.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 = obj.pose.bones[bones['nose.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 = obj.pose.bones[bones['chin.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 = obj.pose.bones[bones['ear.L.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 = obj.pose.bones[bones['ear.R.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 = obj.pose.bones[bones['brow.B.L.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 = obj.pose.bones[bones['lid.T.L.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 = obj.pose.bones[bones['brow.B.R.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 = obj.pose.bones[bones['lid.T.R.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 = obj.pose.bones[bones['forehead.L.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 = obj.pose.bones[bones['forehead.R.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 = obj.pose.bones[bones['nose.L']] + 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 = obj.pose.bones[bones['nose.R']] + 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 = obj.pose.bones[bones['tongue.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 = obj.pose.bones[bones['nose.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 = obj.pose.bones[bones['ear.L.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 = obj.pose.bones[bones['ear.R.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 = obj.pose.bones[bones['brow.B.L.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 = obj.pose.bones[bones['lid.T.L.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 = obj.pose.bones[bones['brow.B.R.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 = obj.pose.bones[bones['lid.T.R.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 = obj.pose.bones[bones['temple.L']] + 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 = obj.pose.bones[bones['temple.R']] + 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 = obj.pose.bones[bones['nose.L.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 = obj.pose.bones[bones['nose.R.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 = obj.pose.bones[bones['nose.004']] + 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 = obj.pose.bones[bones['ear.L.004']] + 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 = obj.pose.bones[bones['ear.R.004']] + 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 = obj.pose.bones[bones['lid.B.L']] + 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 = obj.pose.bones[bones['lid.B.R']] + 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 = obj.pose.bones[bones['jaw.L']] + 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 = obj.pose.bones[bones['jaw.R']] + 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 = obj.pose.bones[bones['lid.B.L.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 = obj.pose.bones[bones['lid.B.R.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 = obj.pose.bones[bones['jaw.L.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 = obj.pose.bones[bones['jaw.R.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 = obj.pose.bones[bones['lid.B.L.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 = obj.pose.bones[bones['lid.B.R.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 = obj.pose.bones[bones['chin.L']] + 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 = obj.pose.bones[bones['chin.R']] + 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 = obj.pose.bones[bones['lid.B.L.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 = obj.pose.bones[bones['lid.B.R.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 = obj.pose.bones[bones['cheek.B.L']] + 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 = obj.pose.bones[bones['cheek.B.R']] + 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 = obj.pose.bones[bones['cheek.B.L.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 = obj.pose.bones[bones['cheek.B.R.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 = obj.pose.bones[bones['brow.T.L']] + 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 = obj.pose.bones[bones['brow.T.R']] + 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 = obj.pose.bones[bones['brow.T.L.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 = obj.pose.bones[bones['brow.T.R.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 = obj.pose.bones[bones['brow.T.L.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 = obj.pose.bones[bones['brow.T.R.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 = obj.pose.bones[bones['brow.T.L.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 = obj.pose.bones[bones['brow.T.R.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' + + 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 + + +def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [ + ( 0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ), + ( -0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ), + ( 0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ), + ( -0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ), + ] + + edges = [(0, 1), (2, 3), (0, 2), (3, 1) ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + mesh.update() + return obj + else: + return None + diff --git a/rigify/legacy/rigs/pitchipoy/super_finger.py b/rigify/legacy/rigs/pitchipoy/super_finger.py new file mode 100644 index 00000000..86733921 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_finger.py @@ -0,0 +1,414 @@ +import bpy +from mathutils import Vector +from ...utils import copy_bone, flip_bone +from ...utils import strip_org, make_deformer_name, connected_children_names, make_mechanism_name +from ...utils import create_circle_widget, create_sphere_widget, create_widget +from ...utils import MetarigError +from rna_prop_ui import rna_idprop_ui_prop_get + +script = """ +controls = [%s] +master_name = '%s' +if is_selected(controls): + layout.prop(pose_bones[master_name], '["%s"]', text="Curvature", slider=True) +""" + +class Rig: + + def __init__(self, obj, bone_name, params): + self.obj = obj + self.org_bones = [bone_name] + connected_children_names(obj, bone_name) + self.params = params + + if len(self.org_bones) <= 1: + raise MetarigError("RIGIFY ERROR: Bone '%s': listen bro, that finger rig jusaint put tugetha rite. A little hint, use more than one bone!!" % (strip_org(bone_name))) + + + def generate(self): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Bone name lists + ctrl_chain = [] + def_chain = [] + mch_chain = [] + mch_drv_chain = [] + + # Create ctrl master bone + org_name = self.org_bones[0] + temp_name = strip_org(self.org_bones[0]) + + suffix = temp_name[-2:] + master_name = temp_name[:-5] + "_master" + suffix + master_name = copy_bone( self.obj, org_name, master_name ) + ctrl_bone_master = eb[ master_name ] + + ## Parenting bug fix ?? + ctrl_bone_master.use_connect = False + ctrl_bone_master.parent = None + + ctrl_bone_master.tail += ( eb[ org_bones[-1] ].tail - eb[org_name].head ) * 1.25 + + for bone in org_bones: + eb[bone].use_connect = False + if org_bones.index( bone ) != 0: + eb[bone].parent = None + + # Creating the bone chains + for i in range(len(self.org_bones)): + + name = self.org_bones[i] + ctrl_name = strip_org(name) + + # Create control bones + ctrl_bone = copy_bone( self.obj, name, ctrl_name ) + ctrl_bone_e = eb[ ctrl_name ] + + # Create deformation bones + def_name = make_deformer_name( ctrl_name ) + def_bone = copy_bone( self.obj, name, def_name ) + + # Create mechanism bones + mch_name = make_mechanism_name( ctrl_name ) + mch_bone = copy_bone( self.obj, name, mch_name ) + + # Create mechanism driver bones + drv_name = make_mechanism_name(ctrl_name) + "_drv" + mch_bone_drv = copy_bone(self.obj, name, drv_name) + mch_bone_drv_e = eb[drv_name] + + # Adding to lists + ctrl_chain += [ctrl_name] + def_chain += [def_bone] + mch_chain += [mch_bone] + mch_drv_chain += [drv_name] + + # Restoring org chain parenting + for bone in org_bones[1:]: + eb[bone].parent = eb[ org_bones[ org_bones.index(bone) - 1 ] ] + + # Parenting the master bone to the first org + ctrl_bone_master = eb[ master_name ] + ctrl_bone_master.parent = eb[ org_bones[0] ] + + # Parenting chain bones + for i in range(len(self.org_bones)): + # Edit bone references + def_bone_e = eb[def_chain[i]] + ctrl_bone_e = eb[ctrl_chain[i]] + mch_bone_e = eb[mch_chain[i]] + mch_bone_drv_e = eb[mch_drv_chain[i]] + + if i == 0: + # First ctl bone + ctrl_bone_e.parent = mch_bone_drv_e + ctrl_bone_e.use_connect = False + # First def bone + def_bone_e.parent = eb[self.org_bones[i]].parent + def_bone_e.use_connect = False + # First mch bone + mch_bone_e.parent = eb[self.org_bones[i]].parent + mch_bone_e.use_connect = False + # First mch driver bone + mch_bone_drv_e.parent = eb[self.org_bones[i]].parent + mch_bone_drv_e.use_connect = False + else: + # The rest + ctrl_bone_e.parent = mch_bone_drv_e + ctrl_bone_e.use_connect = False + + def_bone_e.parent = eb[def_chain[i-1]] + def_bone_e.use_connect = True + + mch_bone_drv_e.parent = eb[ctrl_chain[i-1]] + mch_bone_drv_e.use_connect = False + + # Parenting mch bone + mch_bone_e.parent = ctrl_bone_e + mch_bone_e.use_connect = False + + # Creating tip conrtol bone + tip_name = copy_bone( self.obj, org_bones[-1], temp_name ) + ctrl_bone_tip = eb[ tip_name ] + flip_bone( self.obj, tip_name ) + ctrl_bone_tip.length /= 2 + + ctrl_bone_tip.parent = eb[ctrl_chain[-1]] + + bpy.ops.object.mode_set(mode ='OBJECT') + + pb = self.obj.pose.bones + + # Setting pose bones locks + pb_master = pb[master_name] + pb_master.lock_scale = True,False,True + + pb[tip_name].lock_scale = True,True,True + pb[tip_name].lock_rotation = True,True,True + pb[tip_name].lock_rotation_w = True + + pb_master['finger_curve'] = 0.0 + prop = rna_idprop_ui_prop_get(pb_master, 'finger_curve') + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = "Rubber hose finger cartoon effect" + + # Pose settings + for org, ctrl, deform, mch, mch_drv in zip(self.org_bones, ctrl_chain, def_chain, mch_chain, mch_drv_chain): + + # Constraining the org bones + #con = pb[org].constraints.new('COPY_TRANSFORMS') + #con.target = self.obj + #con.subtarget = ctrl + + # Constraining the deform bones + con = pb[deform].constraints.new('COPY_TRANSFORMS') + con.target = self.obj + con.subtarget = mch + + # Constraining the mch bones + if mch_chain.index(mch) == 0: + con = pb[mch].constraints.new('COPY_LOCATION') + con.target = self.obj + con.subtarget = ctrl + + con = pb[mch].constraints.new('COPY_SCALE') + con.target = self.obj + con.subtarget = ctrl + + con = pb[mch].constraints.new('DAMPED_TRACK') + con.target = self.obj + con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1] + + con = pb[mch].constraints.new('STRETCH_TO') + con.target = self.obj + con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1] + con.volume = 'NO_VOLUME' + + elif mch_chain.index(mch) == len(mch_chain) - 1: + con = pb[mch].constraints.new('DAMPED_TRACK') + con.target = self.obj + con.subtarget = tip_name + + con = pb[mch].constraints.new('STRETCH_TO') + con.target = self.obj + con.subtarget = tip_name + con.volume = 'NO_VOLUME' + else: + con = pb[mch].constraints.new('DAMPED_TRACK') + con.target = self.obj + con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1] + + con = pb[mch].constraints.new('STRETCH_TO') + con.target = self.obj + con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1] + con.volume = 'NO_VOLUME' + + # Constraining and driving mch driver bones + pb[mch_drv].rotation_mode = 'YZX' + + if mch_drv_chain.index(mch_drv) == 0: + # Constraining to master bone + con = pb[mch_drv].constraints.new('COPY_LOCATION') + con.target = self.obj + con.subtarget = master_name + + con = pb[mch_drv].constraints.new('COPY_ROTATION') + con.target = self.obj + con.subtarget = master_name + con.target_space = 'LOCAL' + con.owner_space = 'LOCAL' + + else: + # Match axis to expression + options = { + "X" : { "axis" : 0, + "expr" : '(1-sy)*pi' }, + "-X" : { "axis" : 0, + "expr" : '-((1-sy)*pi)' }, + "Y" : { "axis" : 1, + "expr" : '(1-sy)*pi' }, + "-Y" : { "axis" : 1, + "expr" : '-((1-sy)*pi)' }, + "Z" : { "axis" : 2, + "expr" : '(1-sy)*pi' }, + "-Z" : { "axis" : 2, + "expr" : '-((1-sy)*pi)' } + } + + axis = self.params.primary_rotation_axis + + # Drivers + drv = pb[mch_drv].driver_add("rotation_euler", options[axis]["axis"]).driver + drv.type = 'SCRIPTED' + drv.expression = options[axis]["expr"] + drv_var = drv.variables.new() + drv_var.name = 'sy' + drv_var.type = "SINGLE_PROP" + drv_var.targets[0].id = self.obj + drv_var.targets[0].data_path = pb[master_name].path_from_id() + '.scale.y' + + # Setting bone curvature setting, costum property, and drivers + def_bone = self.obj.data.bones[deform] + + def_bone.bbone_segments = 8 + drv = def_bone.driver_add("bbone_in").driver # Ease in + + drv.type='SUM' + drv_var = drv.variables.new() + drv_var.name = "curvature" + drv_var.type = "SINGLE_PROP" + drv_var.targets[0].id = self.obj + drv_var.targets[0].data_path = pb_master.path_from_id() + '["finger_curve"]' + + drv = def_bone.driver_add("bbone_out").driver # Ease out + + drv.type='SUM' + drv_var = drv.variables.new() + drv_var.name = "curvature" + drv_var.type = "SINGLE_PROP" + drv_var.targets[0].id = self.obj + drv_var.targets[0].data_path = pb_master.path_from_id() + '["finger_curve"]' + + + # Assigning shapes to control bones + create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5) + + # Create ctrl master widget + w = create_widget(self.obj, master_name) + if w is not None: + mesh = w.data + verts = [(0, 0, 0), (0, 1, 0), (0.05, 1, 0), (0.05, 1.1, 0), (-0.05, 1.1, 0), (-0.05, 1, 0)] + if 'Z' in self.params.primary_rotation_axis: + # Flip x/z coordinates + temp = [] + for v in verts: + temp += [(v[2], v[1], v[0])] + verts = temp + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 1)] + mesh.from_pydata(verts, edges, []) + mesh.update() + + # Create tip control widget + create_circle_widget(self.obj, tip_name, radius=0.3, head_tail=0.0) + + # Create UI + controls_string = ", ".join( + ["'" + x + "'" for x in ctrl_chain] + ) + ", " + "'" + master_name + "'" + return [script % (controls_string, master_name, 'finger_curve')] + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + items = [('X', 'X', ''), ('Y', 'Y', ''), ('Z', 'Z', ''), ('-X', '-X', ''), ('-Y', '-Y', ''), ('-Z', '-Z', '')] + params.primary_rotation_axis = bpy.props.EnumProperty(items=items, name="Primary Rotation Axis", default='X') + + +def parameters_ui(layout, params): + """ Create the ui for the rig parameters. + """ + r = layout.row() + r.label(text="Bend rotation axis:") + r.prop(params, "primary_rotation_axis", 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('palm.04.L') + bone.head[:] = 0.0043, -0.0030, -0.0026 + bone.tail[:] = 0.0642, 0.0037, -0.0469 + bone.roll = -2.5155 + bone.use_connect = False + bones['palm.04.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.01.L') + bone.head[:] = 0.0642, 0.0037, -0.0469 + bone.tail[:] = 0.0703, 0.0039, -0.0741 + bone.roll = -1.9749 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.04.L']] + bones['f_pinky.01.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.02.L') + bone.head[:] = 0.0703, 0.0039, -0.0741 + bone.tail[:] = 0.0732, 0.0044, -0.0965 + bone.roll = -1.9059 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.01.L']] + bones['f_pinky.02.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.03.L') + bone.head[:] = 0.0732, 0.0044, -0.0965 + bone.tail[:] = 0.0725, 0.0046, -0.1115 + bone.roll = -1.7639 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.02.L']] + bones['f_pinky.03.L'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['palm.04.L']] + 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 = 'YXZ' + pbone = obj.pose.bones[bones['f_pinky.01.L']] + pbone.rigify_type = 'pitchipoy.simple_tentacle' + 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' + try: + pbone.rigify_parameters.separate_extra_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.extra_layers = [False, False, False, False, False, 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] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_extra_layers = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_pinky.02.L']] + 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 = obj.pose.bones[bones['f_pinky.03.L']] + 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' + + 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 + + + + + diff --git a/rigify/legacy/rigs/pitchipoy/super_palm.py b/rigify/legacy/rigs/pitchipoy/super_palm.py new file mode 100644 index 00000000..68d38958 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_palm.py @@ -0,0 +1,324 @@ +# ##### 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 re +from math import cos, pi + +import bpy + +from ...utils import MetarigError +from ...utils import copy_bone +from ...utils import strip_org, deformer +from ...utils import create_widget + + +def bone_siblings(obj, bone): + """ Returns a list of the siblings of the given bone. + This requires that the bones has a parent. + + """ + parent = obj.data.bones[bone].parent + + if parent is None: + return [] + + bones = [] + + for b in parent.children: + if b.name != bone: + bones += [b.name] + + return bones + + +def bone_distance(obj, bone1, bone2): + """ Returns the distance between two bones. + + """ + vec = obj.data.bones[bone1].head - obj.data.bones[bone2].head + return vec.length + + +class Rig: + """ A "palm" rig. A set of sibling bones that bend with each other. + This is a control and deformation rig. + + """ + def __init__(self, obj, bone, params): + """ Gather and validate data about the rig. + """ + self.obj = obj + self.params = params + + siblings = bone_siblings(obj, bone) + + if len(siblings) == 0: + raise MetarigError( + "RIGIFY ERROR: Bone '%s': must have a parent and at least one sibling" % + (strip_org(bone))) + + # Sort list by name and distance + siblings.sort() + siblings.sort(key=lambda b: bone_distance(obj, bone, b)) + + self.org_bones = [bone] + siblings + + # Get rig parameters + self.palm_rotation_axis = params.palm_rotation_axis + + def generate(self): + """ Generate the rig. + Do NOT modify any of the original bones, except for adding constraints. + The main armature should be selected and active before this is called. + + """ + bpy.ops.object.mode_set(mode='EDIT') + + # Figure out the name for the control bone (remove the last .##) + last_bone = self.org_bones[-1:][0] + ctrl_name = re.sub("([0-9]+\.)", "", strip_org(last_bone)[::-1], count=1)[::-1] + + # Make control bone + ctrl = copy_bone(self.obj, last_bone, ctrl_name) + + # Make deformation bones + def_bones = [] + for bone in self.org_bones: + b = copy_bone(self.obj, bone, deformer(strip_org(bone))) + def_bones += [b] + + # Parenting + eb = self.obj.data.edit_bones + + # turn off inherit scale for all ORG-bones to prevent undesired transformations + + for o in self.org_bones: + eb[o].use_inherit_scale = False + + for d, b in zip(def_bones, self.org_bones): + eb[d].use_connect = False + eb[d].parent = eb[b] + + # Get ORG parent bone + org_parent = eb[self.org_bones[0]].parent.name + + # Get DEF parent from ORG parent + def_parent = deformer(strip_org(org_parent)) + + # Switch parent + for o in self.org_bones: + eb[o].parent = eb[def_parent] + eb[ctrl].parent = eb[def_parent] + + # Constraints + bpy.ops.object.mode_set(mode='OBJECT') + pb = self.obj.pose.bones + + i = 0 + div = len(self.org_bones) - 1 + for b in self.org_bones: + con = pb[b].constraints.new('COPY_TRANSFORMS') + con.name = "copy_transforms" + con.target = self.obj + con.subtarget = ctrl + con.target_space = 'LOCAL' + con.owner_space = 'LOCAL' + con.influence = i / div + + con = pb[b].constraints.new('COPY_SCALE') + con.name = "copy_scale" + con.target = self.obj + con.subtarget = def_parent + con.target_space = 'WORLD' + con.owner_space = 'WORLD' + con.influence = 1 + + con = pb[b].constraints.new('COPY_ROTATION') + con.name = "copy_rotation" + con.target = self.obj + con.subtarget = ctrl + con.target_space = 'LOCAL' + con.owner_space = 'LOCAL' + if 'X' in self.palm_rotation_axis: + con.invert_x = True + con.use_x = True + con.use_z = False + else: + con.invert_z = True + con.use_x = False + con.use_z = True + con.use_y = False + + con.influence = (i / div) - (1 - cos((i * pi / 2) / div)) + + i += 1 + + # Create control widget + w = create_widget(self.obj, ctrl) + if w is not None: + mesh = w.data + verts = [ + (0.1578, 0.0, -0.3), + (0.1578, 1.0, -0.2), + (-0.1578, 1.0, -0.2), + (-0.1578, -0.0, -0.3), + (-0.1578, -0.0, 0.3), + (-0.1578, 1.0, 0.2), + (0.1578, 1.0, 0.2), + (0.1578, 0.0, 0.3), + (0.1578, 0.25, -0.275), + (-0.1578, 0.25, -0.275), + (0.1578, 0.75, -0.225), + (-0.1578, 0.75, -0.225), + (0.1578, 0.75, 0.225), + (0.1578, 0.25, 0.275), + (-0.1578, 0.25, 0.275), + (-0.1578, 0.75, 0.225), + ] + + if 'Z' in self.palm_rotation_axis: + # Flip x/z coordinates + verts = [v[::-1] for v in verts] + + edges = [ + (1, 2), (0, 3), (4, 7), (5, 6), + (8, 0), (9, 3), (10, 1), (11, 2), + (12, 6), (13, 7), (4, 14), (15, 5), + (10, 8), (11, 9), (15, 14), (12, 13), + ] + mesh.from_pydata(verts, edges, []) + mesh.update() + + mod = w.modifiers.new("subsurf", 'SUBSURF') + mod.levels = 2 + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + + """ + items = [('X', 'X', ''), ('Z', 'Z', '')] + params.palm_rotation_axis = bpy.props.EnumProperty( + items=items, + name="Palm Rotation Axis", + default='X', + ) + + +def parameters_ui(layout, params): + """ Create the ui for the rig parameters. + + """ + r = layout.row() + r.label(text="Primary rotation axis:") + r.prop(params, "palm_rotation_axis", 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('palm.parent') + bone.head[:] = 0.0000, 0.0000, 0.0000 + bone.tail[:] = 0.0577, 0.0000, -0.0000 + bone.roll = 3.1416 + bone.use_connect = False + bones['palm.parent'] = bone.name + bone = arm.edit_bones.new('palm.04') + bone.head[:] = 0.0577, 0.0315, -0.0000 + bone.tail[:] = 0.1627, 0.0315, -0.0000 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.parent']] + bones['palm.04'] = bone.name + bone = arm.edit_bones.new('palm.03') + bone.head[:] = 0.0577, 0.0105, -0.0000 + bone.tail[:] = 0.1627, 0.0105, -0.0000 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.parent']] + bones['palm.03'] = bone.name + bone = arm.edit_bones.new('palm.02') + bone.head[:] = 0.0577, -0.0105, -0.0000 + bone.tail[:] = 0.1627, -0.0105, -0.0000 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.parent']] + bones['palm.02'] = bone.name + bone = arm.edit_bones.new('palm.01') + bone.head[:] = 0.0577, -0.0315, -0.0000 + bone.tail[:] = 0.1627, -0.0315, -0.0000 + bone.roll = 3.1416 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.parent']] + bones['palm.01'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['palm.parent']] + 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 = obj.pose.bones[bones['palm.04']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone = obj.pose.bones[bones['palm.03']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone = obj.pose.bones[bones['palm.02']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone = obj.pose.bones[bones['palm.01']] + pbone.rigify_type = 'palm' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + + 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 diff --git a/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py new file mode 100644 index 00000000..e1ff5b0e --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py @@ -0,0 +1,911 @@ +import bpy +from mathutils import Vector +from ...utils import copy_bone, flip_bone, put_bone, org +from ...utils import strip_org, make_deformer_name, connected_children_names +from ...utils import create_circle_widget, create_sphere_widget, create_widget +from ...utils import MetarigError, make_mechanism_name, create_cube_widget +from rna_prop_ui import rna_idprop_ui_prop_get + +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): + """ Initialize torso rig and key rig properties """ + + 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 ] ) + + # 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" + ) + + # 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, pivot ): + """ Create the pivot control and mechanism bones """ + 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 org in org_bones: + def_name = make_deformer_name( strip_org( org ) ) + def_name = copy_bone( self.obj, org, def_name ) + def_bones.append( def_name ) + + 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 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 + + # 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 currnet + # 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 ): + # MCH bones + + # 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 ], + }) + + pb = self.obj.pose.bones + + for t in tweaks: + if t != bones['neck']['ctrl']: + pb[t].rotation_mode = 'ZXY' + + + 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 + + # deform bones bbone segements + for bone in bones['def'][:-1]: + self.obj.data.bones[bone].bbone_segments = 8 + + self.obj.data.bones[ bones['def'][0] ].bbone_in = 0.0 + self.obj.data.bones[ bones['def'][-2] ].bbone_out = 0.0 + + # 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 torso bone + 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() + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Clear parents for org bones + for bone in self.org_bones: + 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' ] ] + + 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 ) + + # 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 ) + + + 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'] ] + + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) + 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 + """ + 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, "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.0552, 1.0099 + bone.tail[:] = 0.0000, 0.0172, 1.1573 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.0172, 1.1573 + bone.tail[:] = 0.0000, 0.0004, 1.2929 + 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.0004, 1.2929 + bone.tail[:] = 0.0000, 0.0059, 1.4657 + 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.0059, 1.4657 + bone.tail[:] = 0.0000, 0.0114, 1.6582 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, 0.0114, 1.6582 + bone.tail[:] = 0.0000, -0.0067, 1.7197 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, -0.0067, 1.7197 + bone.tail[:] = 0.0000, -0.0247, 1.7813 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.004']] + bones['spine.005'] = bone.name + + bone = arm.edit_bones.new('spine.006') + bone.head[:] = 0.0000, -0.0247, 1.7813 + bone.tail[:] = 0.0000, -0.0247, 1.9796 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.005']] + bones['spine.006'] = bone.name + + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'pitchipoy.super_torso_turbo' + 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' + try: + pbone.rigify_parameters.chain_bone_controls = "1, 2, 3" + except AttributeError: + pass + try: + pbone.rigify_parameters.neck_pos = 5 + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, 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] + except AttributeError: + pass + 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 = 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 = 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 = obj.pose.bones[bones['spine.004']] + 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 = obj.pose.bones[bones['spine.005']] + 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 = obj.pose.bones[bones['spine.006']] + 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' + + 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 diff --git a/rigify/legacy/rigs/pitchipoy/super_widgets.py b/rigify/legacy/rigs/pitchipoy/super_widgets.py new file mode 100644 index 00000000..aee6c14e --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/super_widgets.py @@ -0,0 +1,164 @@ +import bpy +import importlib +import importlib +from ...utils import create_widget + +WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer. +MODULE_NAME = "super_widgets" # Windows/Mac blender is weird, so __package__ doesn't work + + +def create_eye_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(1.1920928955078125e-07*size, 0.5000000596046448*size, 0.0*size), (-0.12940943241119385*size, 0.482962965965271*size, 0.0*size), (-0.24999988079071045*size, 0.4330127537250519*size, 0.0*size), (-0.35355329513549805*size, 0.35355344414711*size, 0.0*size), (-0.43301260471343994*size, 0.2500000596046448*size, 0.0*size), (-0.4829627275466919*size, 0.12940959632396698*size, 0.0*size), (-0.49999988079071045*size, 1.0094120739267964e-07*size, 0.0*size), (-0.482962965965271*size, -0.12940940260887146*size, 0.0*size), (-0.43301260471343994*size, -0.24999986588954926*size, 0.0*size), (-0.3535534143447876*size, -0.35355323553085327*size, 0.0*size), (-0.25*size, -0.43301257491111755*size, 0.0*size), (-0.1294095516204834*size, -0.48296281695365906*size, 0.0*size), (-1.1920928955078125e-07*size, -0.4999999403953552*size, 0.0*size), (0.12940943241119385*size, -0.4829629063606262*size, 0.0*size), (0.24999988079071045*size, -0.4330127537250519*size, 0.0*size), (0.35355329513549805*size, -0.35355353355407715*size, 0.0*size), (0.4330127239227295*size, -0.25000008940696716*size, 0.0*size), (0.482962965965271*size, -0.12940965592861176*size, 0.0*size), (0.5000001192092896*size, -1.6926388468618825e-07*size, 0.0*size), (0.48296308517456055*size, 0.1294093281030655*size, 0.0*size), (0.4330129623413086*size, 0.24999980628490448*size, 0.0*size), (0.35355377197265625*size, 0.35355323553085327*size, 0.0*size), (0.25000035762786865*size, 0.43301260471343994*size, 0.0*size), (0.1294100284576416*size, 0.48296287655830383*size, 0.0*size), ] + edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_eyes_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.8928930759429932*size, -0.7071065902709961*size, 0.0*size), (0.8928932547569275*size, 0.7071067690849304*size, 0.0*size), (-1.8588197231292725*size, -0.9659252762794495*size, 0.0*size), (-2.100001096725464*size, -0.8660248517990112*size, 0.0*size), (-2.3071072101593018*size, -0.7071059942245483*size, 0.0*size), (-2.4660258293151855*size, -0.49999913573265076*size, 0.0*size), (-2.5659260749816895*size, -0.258818119764328*size, 0.0*size), (-2.5999999046325684*size, 8.575012770961621e-07*size, 0.0*size), (-2.5659255981445312*size, 0.2588198482990265*size, 0.0*size), (-2.4660253524780273*size, 0.5000006556510925*size, 0.0*size), (-2.3071064949035645*size, 0.7071075439453125*size, 0.0*size), (-2.099999189376831*size, 0.866025984287262*size, 0.0*size), (-1.8588184118270874*size, 0.9659261703491211*size, 0.0*size), (-1.5999996662139893*size, 1.000000238418579*size, 0.0*size), (-1.341180443763733*size, 0.9659258723258972*size, 0.0*size), (-1.0999995470046997*size, 0.8660253882408142*size, 0.0*size), (-0.8928929567337036*size, 0.7071067094802856*size, 0.0*size), (-0.892893373966217*size, -0.7071066498756409*size, 0.0*size), (-1.100000262260437*size, -0.8660252690315247*size, 0.0*size), (-1.3411810398101807*size, -0.9659255743026733*size, 0.0*size), (1.600000023841858*size, 1.0*size, 0.0*size), (1.3411810398101807*size, 0.9659258127212524*size, 0.0*size), (1.100000023841858*size, 0.8660253882408142*size, 0.0*size), (-1.600000262260437*size, -0.9999997615814209*size, 0.0*size), (1.0999997854232788*size, -0.8660252690315247*size, 0.0*size), (1.341180682182312*size, -0.9659257531166077*size, 0.0*size), (1.5999996662139893*size, -1.0*size, 0.0*size), (1.8588186502456665*size, -0.965925931930542*size, 0.0*size), (2.0999996662139893*size, -0.8660256266593933*size, 0.0*size), (2.3071064949035645*size, -0.7071071863174438*size, 0.0*size), (2.4660253524780273*size, -0.5000002980232239*size, 0.0*size), (2.5659255981445312*size, -0.25881943106651306*size, 0.0*size), (2.5999999046325684*size, -4.649122899991198e-07*size, 0.0*size), (2.5659260749816895*size, 0.25881853699684143*size, 0.0*size), (2.4660258293151855*size, 0.4999994933605194*size, 0.0*size), (2.3071072101593018*size, 0.707106351852417*size, 0.0*size), (2.1000006198883057*size, 0.8660250902175903*size, 0.0*size), (1.8588197231292725*size, 0.9659256339073181*size, 0.0*size), (-1.8070557117462158*size, -0.7727401852607727*size, 0.0*size), (-2.0000009536743164*size, -0.6928198337554932*size, 0.0*size), (-2.1656856536865234*size, -0.5656847357749939*size, 0.0*size), (-2.292820692062378*size, -0.3999992609024048*size, 0.0*size), (-2.3727407455444336*size, -0.20705445110797882*size, 0.0*size), (-2.3999998569488525*size, 7.336847716032935e-07*size, 0.0*size), (-2.3727405071258545*size, 0.207055926322937*size, 0.0*size), (-2.2928202152252197*size, 0.40000057220458984*size, 0.0*size), (-2.1656851768493652*size, 0.5656861066818237*size, 0.0*size), (-1.9999992847442627*size, 0.6928208470344543*size, 0.0*size), (-1.8070547580718994*size, 0.7727410197257996*size, 0.0*size), (-1.5999996662139893*size, 0.8000002503395081*size, 0.0*size), (-1.3929443359375*size, 0.7727407813072205*size, 0.0*size), (-1.1999995708465576*size, 0.6928203701972961*size, 0.0*size), (-1.0343143939971924*size, 0.5656854510307312*size, 0.0*size), (-1.0343146324157715*size, -0.5656852722167969*size, 0.0*size), (-1.2000001668930054*size, -0.6928201913833618*size, 0.0*size), (-1.3929448127746582*size, -0.7727404236793518*size, 0.0*size), (-1.6000001430511475*size, -0.7999997735023499*size, 0.0*size), (1.8070557117462158*size, 0.772739827632904*size, 0.0*size), (2.0000009536743164*size, 0.6928195953369141*size, 0.0*size), (2.1656856536865234*size, 0.5656843781471252*size, 0.0*size), (2.292820692062378*size, 0.39999890327453613*size, 0.0*size), (2.3727407455444336*size, 0.20705409348011017*size, 0.0*size), (2.3999998569488525*size, -1.0960745839838637e-06*size, 0.0*size), (2.3727405071258545*size, -0.20705628395080566*size, 0.0*size), (2.2928202152252197*size, -0.4000009298324585*size, 0.0*size), (2.1656851768493652*size, -0.5656863451004028*size, 0.0*size), (1.9999992847442627*size, -0.692821204662323*size, 0.0*size), (1.8070547580718994*size, -0.7727413773536682*size, 0.0*size), (1.5999996662139893*size, -0.8000004887580872*size, 0.0*size), (1.3929443359375*size, -0.7727410197257996*size, 0.0*size), (1.1999995708465576*size, -0.6928204894065857*size, 0.0*size), (1.0343143939971924*size, -0.5656855702400208*size, 0.0*size), (1.0343146324157715*size, 0.5656850337982178*size, 0.0*size), (1.2000004053115845*size, 0.6928199529647827*size, 0.0*size), (1.3929448127746582*size, 0.7727401852607727*size, 0.0*size), (1.6000001430511475*size, 0.7999995350837708*size, 0.0*size), ] + edges = [(24, 0), (1, 22), (16, 1), (17, 0), (23, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (21, 20), (22, 21), (13, 14), (14, 15), (15, 16), (17, 18), (18, 19), (19, 23), (25, 24), (26, 25), (27, 26), (28, 27), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (20, 37), (56, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49), (49, 50), (50, 51), (51, 52), (53, 54), (54, 55), (55, 56), (75, 57), (57, 58), (58, 59), (59, 60), (60, 61), (61, 62), (62, 63), (63, 64), (64, 65), (65, 66), (66, 67), (67, 68), (68, 69), (69, 70), (70, 71), (72, 73), (73, 74), (74, 75), (52, 72), (53, 71), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_ear_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(-2.4903741291382175e-09*size, 1.0*size, -3.123863123732917e-08*size), (-7.450580596923828e-09*size, 0.9829629063606262*size, 0.0776456817984581*size), (-1.4901161193847656e-08*size, 0.9330127239227295*size, 0.1499999761581421*size), (-2.9802322387695312e-08*size, 0.8535534143447876*size, 0.2121320217847824*size), (-2.9802322387695312e-08*size, 0.75*size, 0.25980761647224426*size), (-2.9802322387695312e-08*size, 0.6294095516204834*size, 0.2897777259349823*size), (-2.9802322387695312e-08*size, 0.5000000596046448*size, 0.29999998211860657*size), (-5.960464477539063e-08*size, 0.37059056758880615*size, 0.2897777855396271*size), (-5.960464477539063e-08*size, 0.25000008940696716*size, 0.25980767607688904*size), (-4.470348358154297e-08*size, 0.14644670486450195*size, 0.21213211119174957*size), (-4.470348358154297e-08*size, 0.06698736548423767*size, 0.15000009536743164*size), (-4.470348358154297e-08*size, 0.017037123441696167*size, 0.07764581590890884*size), (-3.6718930118695425e-08*size, 0.0*size, 1.1981423142515268e-07*size), (-2.9802322387695312e-08*size, 0.017037034034729004*size, -0.07764559239149094*size), (-2.9802322387695312e-08*size, 0.06698718667030334*size, -0.14999987185001373*size), (-1.4901161193847656e-08*size, 0.14644640684127808*size, -0.21213191747665405*size), (0.0*size, 0.24999985098838806*size, -0.25980761647224426*size), (0.0*size, 0.3705902695655823*size, -0.2897777259349823*size), (0.0*size, 0.4999997615814209*size, -0.30000004172325134*size), (0.0*size, 0.6294092535972595*size, -0.2897777855396271*size), (0.0*size, 0.7499997615814209*size, -0.2598077356815338*size), (1.4901161193847656e-08*size, 0.8535531759262085*size, -0.21213220059871674*size), (0.0*size, 0.9330125451087952*size, -0.15000019967556*size), (0.0*size, 0.9829628467559814*size, -0.07764596492052078*size), ] + edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_jaw_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), (0.0*size, 1.153113603591919*size, 0.0*size), (-0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (-0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.0*size, 1.153113603591919*size, 0.18649044632911682*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (-0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), ] + edges = [(1, 0), (2, 1), (3, 2), (4, 3), (9, 4), (6, 5), (7, 6), (8, 7), (15, 8), (5, 0), (11, 10), (12, 11), (13, 12), (14, 13), (9, 14), (17, 16), (18, 17), (19, 18), (15, 19), (16, 10), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_teeth_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.6314387321472168*size, 0.4999997019767761*size, 0.09999999403953552*size), (0.5394065976142883*size, 0.29289281368255615*size, 0.09999999403953552*size), (0.3887903690338135*size, 0.1339743733406067*size, 0.09999999403953552*size), (0.19801488518714905*size, 0.03407406806945801*size, 0.09999999403953552*size), (-3.4034394502668874e-07*size, 0.0*size, 0.09999999403953552*size), (-0.19801555573940277*size, 0.034074246883392334*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, -0.10000000894069672*size), (-0.6778771877288818*size, 0.7411810755729675*size, -0.10000000894069672*size), (-0.6314389705657959*size, 0.5000001192092896*size, -0.10000000894069672*size), (-0.5394070148468018*size, 0.2928934097290039*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, -0.10000000894069672*size), (-0.19801555573940277*size, 0.034074246883392334*size, -0.10000000894069672*size), (-3.4034394502668874e-07*size, 0.0*size, -0.10000000894069672*size), (0.19801488518714905*size, 0.03407406806945801*size, -0.10000000894069672*size), (0.3887903690338135*size, 0.1339743733406067*size, -0.10000000894069672*size), (0.5394065976142883*size, 0.29289281368255615*size, -0.10000000894069672*size), (0.6314387321472168*size, 0.4999997019767761*size, -0.10000000894069672*size), (0.6778769493103027*size, 0.7411805391311646*size, -0.10000000894069672*size), (0.6999999284744263*size, 0.9999995231628418*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, 0.09999999403953552*size), (-0.5394070148468018*size, 0.2928934097290039*size, 0.09999999403953552*size), (-0.6314389705657959*size, 0.5000001192092896*size, 0.09999999403953552*size), (-0.6778771877288818*size, 0.7411810755729675*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, 0.09999999403953552*size), (0.6778769493103027*size, 0.7411805391311646*size, 0.09999999403953552*size), (0.6999999284744263*size, 0.9999995231628418*size, 0.09999999403953552*size), ] + edges = [(25, 24), (24, 0), (0, 1), (1, 2), (2, 3), (3, 4), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (4, 5), (5, 19), (19, 20), (20, 21), (21, 22), (22, 23), (18, 25), (6, 23), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + +def create_face_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(-0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, -0.25*size, -0.07499998807907104*size), (-0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, -0.25*size, -0.07499998807907104*size), ] + edges = [(4, 5), (5, 1), (1, 0), (0, 4), (5, 6), (6, 2), (2, 1), (6, 7), (7, 3), (3, 2), (7, 4), (0, 3), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_ikarrow_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.0*size, 1.0*size, -0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), (0.0*size, 1.0*size, 0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), ] + edges = [(0, 1), (2, 3), (1, 4), (4, 5), (3, 6), (5, 6), (0, 2), (7, 8), (9, 10), (8, 11), (11, 12), (10, 13), (12, 13), (7, 9), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + +def create_hand_widget(rig, bone_name, size=1.0, bone_transform_name=None): + # Create hand widget + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.0*size, 1.5*size, -0.7000000476837158*size), (1.1920928955078125e-07*size, -0.25*size, -0.6999999284744263*size), (0.0*size, -0.25*size, 0.7000000476837158*size), (-1.1920928955078125e-07*size, 1.5*size, 0.6999999284744263*size), (5.960464477539063e-08*size, 0.7229999899864197*size, -0.699999988079071*size), (-5.960464477539063e-08*size, 0.7229999899864197*size, 0.699999988079071*size), (1.1920928955078125e-07*size, -2.9802322387695312e-08*size, -0.699999988079071*size), (0.0*size, 2.9802322387695312e-08*size, 0.699999988079071*size), ] + edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + + mod = obj.modifiers.new("subsurf", 'SUBSURF') + mod.levels = 2 + return obj + else: + return None + +def create_foot_widget(rig, bone_name, size=1.0, bone_transform_name=None): + # Create hand widget + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(-0.6999998688697815*size, -0.5242648720741272*size, 0.0*size), (-0.7000001072883606*size, 1.2257349491119385*size, 0.0*size), (0.6999998688697815*size, 1.2257351875305176*size, 0.0*size), (0.7000001072883606*size, -0.5242648720741272*size, 0.0*size), (-0.6999998688697815*size, 0.2527350187301636*size, 0.0*size), (0.7000001072883606*size, 0.2527352571487427*size, 0.0*size), (-0.7000001072883606*size, 0.975735068321228*size, 0.0*size), (0.6999998688697815*size, 0.9757352471351624*size, 0.0*size), ] + edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + + mod = obj.modifiers.new("subsurf", 'SUBSURF') + mod.levels = 2 + return obj + else: + return None + +def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(-0.050000108778476715*size, 0.779460072517395*size, -0.2224801927804947*size), (0.049999915063381195*size, 0.779460072517395*size, -0.22248023748397827*size), (0.09999985247850418*size, 0.6790841817855835*size, -0.3658318817615509*size), (-2.3089636158601934e-07*size, 0.5930476188659668*size, -0.488704651594162*size), (-0.10000013560056686*size, 0.6790841817855835*size, -0.3658317029476166*size), (0.04999981075525284*size, 0.6790841817855835*size, -0.36583182215690613*size), (-0.050000183284282684*size, 0.6790841817855835*size, -0.3658318519592285*size), (-0.3658319115638733*size, 0.6790841221809387*size, 0.05000019446015358*size), (-0.3658318817615509*size, 0.6790841221809387*size, -0.04999979957938194*size), (-0.36583176255226135*size, 0.6790841221809387*size, 0.10000018030405045*size), (-0.48870471119880676*size, 0.5930476188659668*size, 2.4472291215715813e-07*size), (-0.3658319413661957*size, 0.679084062576294*size, -0.0999998077750206*size), (-0.22248037159442902*size, 0.7794600129127502*size, -0.04999985918402672*size), (-0.22248034179210663*size, 0.7794600129127502*size, 0.05000016465783119*size), (0.3658319115638733*size, 0.6790841221809387*size, -0.05000000819563866*size), (0.3658319115638733*size, 0.6790841221809387*size, 0.05000000074505806*size), (0.36583179235458374*size, 0.6790841221809387*size, -0.09999998658895493*size), (0.4887046813964844*size, 0.5930476188659668*size, -3.8399143420519977e-08*size), (0.3658319413661957*size, 0.679084062576294*size, 0.10000000149011612*size), (0.050000034272670746*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.04999997466802597*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.09999992698431015*size, 0.679084062576294*size, 0.36583200097084045*size), (1.267315070663244e-07*size, 0.5930474996566772*size, 0.48870477080345154*size), (0.1000000610947609*size, 0.679084062576294*size, 0.3658318519592285*size), (-0.049999915063381195*size, 0.679084062576294*size, 0.3658319413661957*size), (0.05000007897615433*size, 0.679084062576294*size, 0.36583197116851807*size), (0.22248029708862305*size, 0.7794600129127502*size, 0.05000004544854164*size), (0.22248028218746185*size, 0.7794600129127502*size, -0.04999994859099388*size), (-4.752442350763886e-08*size, 0.8284152746200562*size, -0.1499999612569809*size), (-0.03882290795445442*size, 0.8284152746200562*size, -0.14488883316516876*size), (-0.07500004768371582*size, 0.8284152746200562*size, -0.12990377843379974*size), (-0.10606606304645538*size, 0.8284152746200562*size, -0.10606598109006882*size), (-0.1299038827419281*size, 0.8284152746200562*size, -0.07499996572732925*size), (-0.14488893747329712*size, 0.8284152746200562*size, -0.038822825998067856*size), (-0.15000006556510925*size, 0.8284152746200562*size, 2.4781975582754967e-08*size), (-0.1448889672756195*size, 0.8284152746200562*size, 0.038822878152132034*size), (-0.1299038827419281*size, 0.8284152746200562*size, 0.07500001043081284*size), (-0.10606609284877777*size, 0.8284152746200562*size, 0.1060660257935524*size), (-0.0750000923871994*size, 0.8284152746200562*size, 0.12990383803844452*size), (-0.038822952657938004*size, 0.8284152746200562*size, 0.14488889276981354*size), (-1.0593657862045802e-07*size, 0.8284152746200562*size, 0.15000005066394806*size), (0.03882275149226189*size, 0.8284152746200562*size, 0.14488892257213593*size), (0.07499989867210388*size, 0.8284152746200562*size, 0.1299038976430893*size), (0.10606591403484344*size, 0.8284152746200562*size, 0.10606611520051956*size), (0.12990373373031616*size, 0.8284152746200562*size, 0.0750000849366188*size), (0.14488881826400757*size, 0.8284152746200562*size, 0.038822952657938004*size), (0.1499999463558197*size, 0.8284152746200562*size, 1.0584351883835552e-07*size), (0.14488881826400757*size, 0.8284152746200562*size, -0.03882275149226189*size), (0.12990379333496094*size, 0.8284152746200562*size, -0.07499989122152328*size), (0.10606604814529419*size, 0.8284152746200562*size, -0.10606592148542404*size), (0.07500004768371582*size, 0.8284152746200562*size, -0.12990371882915497*size), (0.03882291540503502*size, 0.8284152746200562*size, -0.14488880336284637*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), ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + return obj + else: + return None + + diff --git a/rigify/legacy/rigs/pitchipoy/tentacle.py b/rigify/legacy/rigs/pitchipoy/tentacle.py new file mode 100644 index 00000000..b8d52e88 --- /dev/null +++ b/rigify/legacy/rigs/pitchipoy/tentacle.py @@ -0,0 +1,509 @@ +import bpy +from ...utils import copy_bone +from ...utils import strip_org, make_deformer_name, connected_children_names +from ...utils import make_mechanism_name, put_bone, create_sphere_widget +from ...utils import create_widget, create_circle_widget +from ...utils import MetarigError +from rna_prop_ui import rna_idprop_ui_prop_get + +script = """ +controls = [%s] +master_name = '%s' + +if is_selected( controls ): + layout.prop( pose_bones[ master_name ], '["%s"]', slider = True ) + layout.prop( pose_bones[ master_name ], '["%s"]', slider = True ) +""" + +class Rig: + + def __init__(self, obj, bone_name, params): + self.obj = obj + self.org_bones = [bone_name] + connected_children_names(obj, bone_name) + self.params = params + + if params.tweak_extra_layers: + self.tweak_layers = list( params.tweak_layers ) + else: + self.tweak_layers = None + + if len(self.org_bones) <= 1: + raise MetarigError( + "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name)) + ) + + + def make_mch( self ): + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + org_bones = self.org_bones + mch_parent = self.obj.data.bones[ org_bones[0] ].parent + + mch_parent_name = mch_parent.name # Storing the mch parent's name + + if not mch_parent: + mch_parent = self.obj.data.edit_bones[ org_bones[0] ] + mch_bone = copy_bone( + self.obj, + mch_parent_name, + make_mechanism_name( strip_org( org_bones[0] ) ) + ) + else: + mch_bone = copy_bone( + self.obj, + mch_parent_name, + make_mechanism_name( strip_org( org_bones[0] ) ) + ) + + put_bone( self.obj, mch_bone, eb[ mch_parent_name ].tail ) + + eb[ mch_bone ].length /= 4 # reduce length to fourth of original + + return mch_bone + + + def make_master( self ): + bpy.ops.object.mode_set(mode ='EDIT') + + org_bones = self.org_bones + + master_bone = copy_bone( + self.obj, + org_bones[0], + "master_" + strip_org( org_bones[0] ) + ) + + # Make widgets + bpy.ops.object.mode_set(mode ='OBJECT') + + create_square_widget( self.obj, master_bone ) + + return master_bone + + + def make_controls( self ): + bpy.ops.object.mode_set(mode ='EDIT') + + org_bones = self.org_bones + + ctrl_chain = [] + for i in range( len( org_bones ) ): + name = org_bones[i] + + ctrl_bone = copy_bone( + self.obj, + name, + strip_org(name) + ) + + ctrl_chain.append( ctrl_bone ) + + # Make widgets + bpy.ops.object.mode_set(mode ='OBJECT') + + for ctrl in ctrl_chain: + create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5) + + return ctrl_chain + + + def make_tweaks( self ): + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + org_bones = self.org_bones + + tweak_chain = [] + for i in range( len( org_bones ) + 1 ): + if i == len( org_bones ): + # Make final tweak at the tip of the tentacle + name = org_bones[i-1] + else: + name = org_bones[i] + + tweak_bone = copy_bone( + self.obj, + name, + "tweak_" + strip_org(name) + ) + + tweak_e = eb[ tweak_bone ] + + tweak_e.length /= 2 # Set size to half + + if i == len( org_bones ): + # Position final tweak at the tip + put_bone( self.obj, tweak_bone, eb[ org_bones[-1]].tail ) + + tweak_chain.append( tweak_bone ) + + # Make widgets + bpy.ops.object.mode_set(mode = 'OBJECT') + + for tweak in tweak_chain: + create_sphere_widget( self.obj, tweak ) + + tweak_pb = self.obj.pose.bones[ tweak ] + + # Set locks + if tweak_chain.index( tweak ) != len( tweak_chain ) - 1: + tweak_pb.lock_rotation = (True, False, True) + tweak_pb.lock_scale = (False, True, False) + else: + tweak_pb.lock_rotation_w = True + tweak_pb.lock_rotation = (True, True, True) + tweak_pb.lock_scale = (True, True, True) + + # Set up tweak bone layers + if self.tweak_layers: + tweak_pb.bone.layers = self.tweak_layers + + return tweak_chain + + + def make_deform( self ): + bpy.ops.object.mode_set(mode ='EDIT') + + org_bones = self.org_bones + + def_chain = [] + for i in range( len( org_bones ) ): + name = org_bones[i] + + def_bone = copy_bone( + self.obj, + name, + make_deformer_name(strip_org(name)) + ) + + def_chain.append( def_bone ) + + return def_chain + + + def parent_bones( self, all_bones ): + bpy.ops.object.mode_set(mode ='EDIT') + + org_bones = self.org_bones + eb = self.obj.data.edit_bones + + """ for category in all_bones: + if isinstance( all_bones[category], list ): + for bone in all_bones[category]: + print( "Bone: " + bone ) + eb[bone].parent = None + else: + eb[ all_bones[category] ].parent = None + """ + + # mch bone remains parentless and will be parented to root by rigify + + # Parent master bone + # eb[ all_bones['master'] ].parent = eb[ all_bones['mch'] ] + + # Parent control bones + # ctrls_n_parent = [ all_bones['master'] ] + all_bones['control'] + + for bone in ctrls_n_parent[1:]: + previous_index = ctrls_n_parent.index( bone ) - 1 + eb[ bone ].parent = eb[ ctrls_n_parent[previous_index] ] + + # Parent tweak bones + tweaks = all_bones['tweak'] + for tweak in all_bones['tweak']: + parent = '' + if tweaks.index( tweak ) == len( tweaks ) - 1: + parent = all_bones['control'][ -1 ] + else: + parent = all_bones['control'][ tweaks.index( tweak ) ] + + eb[ tweak ].parent = eb[ parent ] + + # Parent deform bones + for bone in all_bones['deform'][1:]: + previous_index = all_bones['deform'].index( bone ) - 1 + + eb[ bone ].parent = eb[ all_bones['deform'][previous_index] ] + eb[ bone ].use_connect = True + + # Parent org bones ( to tweaks by default, or to the controls ) + for org, tweak in zip( org_bones, all_bones['tweak'] ): + eb[ org ].parent = eb[ tweak ] + + + def make_constraints( self, all_bones ): + bpy.ops.object.mode_set(mode ='OBJECT') + + org_bones = self.org_bones + pb = self.obj.pose.bones + + ## MCH bone constraints + if pb[ org_bones[0] ].parent: + mch_pb = pb[ all_bones['mch'] ] + + con = mch_pb.constraints.new('COPY_LOCATION') + con.target = self.obj + con.subtarget = pb[ org_bones[0] ].parent.name + con.head_tail = 1.0 + + con = mch_pb.constraints.new('COPY_ROTATION') + con.target = self.obj + con.subtarget = pb[ org_bones[0] ].parent.name + + con = mch_pb.constraints.new('COPY_SCALE') + con.target = self.obj + con.subtarget = pb[ org_bones[0] ].parent.name + + """ + # Setting the MCH prop + master_pb = pb[ all_bones['master'] ] + prop_name_r = "rotation_follow" + prop_name_s = "scale_follow" + + prop_names = [ prop_name_r, prop_name_s ] + + for prop_name in prop_names: + master_pb[prop_name] = 1.0 + + prop = rna_idprop_ui_prop_get( master_pb, prop_name ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = prop_name + + # driving the MCH follow rotation switch + + drv = mch_pb.constraints[ + prop_names.index(prop_name) +1 + ].driver_add("influence").driver + + drv.type='SUM' + + var = drv.variables.new() + var.name = prop_name + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + master_pb.path_from_id() + '['+ '"' + prop_name + '"' + ']' + + """ + + ## Deform bones' constraints + ctrls = all_bones['control'] + tweaks = all_bones['tweak' ] + deforms = all_bones['deform' ] + + for deform, tweak, ctrl in zip( deforms, tweaks, ctrls ): + con = pb[deform].constraints.new('COPY_TRANSFORMS') + con.target = self.obj + con.subtarget = tweak + + con = pb[deform].constraints.new('DAMPED_TRACK') + con.target = self.obj + con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ] + + con = pb[deform].constraints.new('STRETCH_TO') + con.target = self.obj + con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ] + + ## Control bones' constraints + if self.params.make_rotations: + if ctrl != ctrls[0]: + con = pb[ctrl].constraints.new('COPY_ROTATION') + con.target = self.obj + con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ] + con.use_offset = True + con.target_space = 'LOCAL' + con.owner_space = 'LOCAL' + + + def generate(self): + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Clear all initial parenting + for bone in self.org_bones: + # eb[ bone ].parent = None + eb[ bone ].use_connect = False + + # Creating all bones + mch = self.make_mch() + # master = self.make_master() + ctrl_chain = self.make_controls() + tweak_chain = self.make_tweaks() + def_chain = self.make_deform() + + all_bones = { + 'mch' : mch, + # 'master' : master, + 'control' : ctrl_chain, + 'tweak' : tweak_chain, + 'deform' : def_chain + } + + self.make_constraints( all_bones ) + self.parent_bones( all_bones ) + + """ + # Create UI + all_controls = all_bones['control'] + all_bones['tweak'] # + [ all_bones['master'] ] + controls_string = ", ".join(["'" + x + "'" for x in all_controls]) + return [script % ( + controls_string, + 'rotation_follow', + 'scale_follow' + )] + """ + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + params.make_rotations = bpy.props.BoolProperty( + name = "Rotations", + default = True, + description = "Make bones follow parent rotation" + ) + + # Setting up extra tweak layers + 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, "make_rotations") + + 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 ): # Layers 0-7 + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range( 16, 24 ): # Layers 16-23 + 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 ): # Layers 8-15 + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range( 24, 32 ): # Layers 24-31 + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + +def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None): + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [ + ( 0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ), + ( -0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ), + ( 0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ), + ( -0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ), + ] + + edges = [(0, 1), (2, 3), (0, 2), (3, 1) ] + faces = [] + + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + mesh.update() + return obj + else: + return None + +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('tentacle') + bone.head[:] = 0.0000, 0.0000, 0.0000 + bone.tail[:] = 0.0000, 0.0000, 1.0000 + bone.roll = 0.0000 + bone.use_connect = False + + bones['tentacle'] = bone.name + + bone = arm.edit_bones.new('tentacle.001') + bone.head[:] = 0.0000, 0.0000, 1.0000 + bone.tail[:] = 0.0000, 0.0000, 2.0000 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tentacle']] + + bones['tentacle.001'] = bone.name + + bone = arm.edit_bones.new('tentacle.002') + bone.head[:] = 0.0000, 0.0000, 2.0000 + bone.tail[:] = 0.0000, 0.0000, 3.0000 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['tentacle.001']] + bones['tentacle.002'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + + pbone = obj.pose.bones[bones['tentacle']] + pbone.rigify_type = 'tentacle' + 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 = obj.pose.bones[bones['tentacle.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 = obj.pose.bones[bones['tentacle.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' + 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 -- cgit v1.2.3