diff --git a/rigify/CREDITS b/rigify/CREDITS index 737abf60768afe1364ee98d329aeb13a82a147a2..38f6de46947e497da79108cf3fe6cdcad5b93428 100644 --- a/rigify/CREDITS +++ b/rigify/CREDITS @@ -20,3 +20,13 @@ IK/FK snapping financial support: - Leslie Chih - Isaac Ah-Loe - Casey "TheLorax" Jones + +### Rigify Version 0.5 ### +Development: +- Lucio Rossi + +Design: +- Ivan Cappiello + +General financial support: +- Mad Entertainment Animation \ No newline at end of file diff --git a/rigify/README b/rigify/README index 7b12589b19859107311707228f1b49ab659962e6..f8cb7656495b1cbf8dfdfb4ce24fe5cba4fedb36 100644 --- a/rigify/README +++ b/rigify/README @@ -227,6 +227,12 @@ button labeled "Encode Sample to Python". This button will generate the python code for create_sample() from the armature you are editing. The generated code appears in a text block called "metarig_sample.py" +IMPLEMENTATION RIGS +------------------- +Starting from version 0.5 you can create a Rig class as an implementation of a wrapper class. +This happens for limb rigs for example, where super_limb is kind of a wrapper class for arm, leg and paws. +To declare a class as an implementation just declare an IMPLEMENTATION constant in the module and set it to True. +Implementation classes are shown in the metarig samples list and generate a sample if a proper create_sample function is implemented, but cannot be directly assigned as a rigify type. GENERATING A PYTHON UI ---------------------- diff --git a/rigify/__init__.py b/rigify/__init__.py index 6e6f751c7461ba52437bc1d17723b8ba083b1368..638260e1a72785480f8ab9c6121dfaf704c0b9b3 100644 --- a/rigify/__init__.py +++ b/rigify/__init__.py @@ -20,9 +20,9 @@ bl_info = { "name": "Rigify", - "version": (0, 4), - "author": "Nathan Vegdahl", - "blender": (2, 66, 0), + "version": (0, 5), + "author": "Nathan Vegdahl, Lucio Rossi, Ivan Cappiello", + "blender": (2, 78, 0), "description": "Automatic rigging from building-block components", "location": "Armature properties, Bone properties, View3d tools panel, Armature Add menu", "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" @@ -42,6 +42,120 @@ else: from . import utils, rig_lists, generate, ui, metarig_menu import bpy +import sys +import os +from bpy.types import AddonPreferences +from bpy.props import BoolProperty + + +class RigifyPreferences(AddonPreferences): + # this must match the addon name, use '__package__' + # when defining this in a submodule of a python package. + bl_idname = __name__ + + def update_legacy(self, context): + if self.legacy_mode: + + if 'ui' in globals() and 'legacy' in str(globals()['ui']): # already in legacy mode. needed when rigify is reloaded + return + else: + rigify_dir = os.path.dirname(os.path.realpath(__file__)) + if rigify_dir not in sys.path: + sys.path.append(rigify_dir) + + unregister() + + globals().pop('utils') + globals().pop('rig_lists') + globals().pop('generate') + globals().pop('ui') + globals().pop('metarig_menu') + + import legacy.utils + import legacy.rig_lists + import legacy.generate + import legacy.ui + import legacy.metarig_menu + + print("ENTERING RIGIFY LEGACY\r\n") + + globals()['utils'] = legacy.utils + globals()['rig_lists'] = legacy.rig_lists + globals()['generate'] = legacy.generate + globals()['ui'] = legacy.ui + globals()['metarig_menu'] = legacy.metarig_menu + + register() + + else: + + rigify_dir = os.path.dirname(os.path.realpath(__file__)) + + if rigify_dir in sys.path: + id = sys.path.index(rigify_dir) + sys.path.pop(id) + + unregister() + + globals().pop('utils') + globals().pop('rig_lists') + globals().pop('generate') + globals().pop('ui') + globals().pop('metarig_menu') + + from . import utils + from . import rig_lists + from . import generate + from . import ui + from . import metarig_menu + + print("EXIT RIGIFY LEGACY\r\n") + + globals()['utils'] = utils + globals()['rig_lists'] = rig_lists + globals()['generate'] = generate + globals()['ui'] = ui + globals()['metarig_menu'] = metarig_menu + + register() + + legacy_mode = BoolProperty( + name='Rigify Legacy Mode', + description='Select if you want to use Rigify in legacy mode', + default=False, + update=update_legacy + ) + + show_expanded = BoolProperty() + + def draw(self, context): + layout = self.layout + column = layout.column() + box = column.box() + + # first stage + expand = getattr(self, 'show_expanded') + icon = 'TRIA_DOWN' if expand else 'TRIA_RIGHT' + col = box.column() + row = col.row() + sub = row.row() + sub.context_pointer_set('addon_prefs', self) + sub.alignment = 'LEFT' + op = sub.operator('wm.context_toggle', text='', icon=icon, + emboss=False) + op.data_path = 'addon_prefs.show_expanded' + sub.label('{}: {}'.format('Rigify', 'Enable Legacy Mode')) + sub = row.row() + sub.alignment = 'RIGHT' + sub.prop(self, 'legacy_mode') + + if expand: + split = col.row().split(percentage=0.15) + split.label('Description:') + split.label(text='When enabled the add-on will run in legacy mode using the old 2.76b feature set.') + + row = layout.row() + row.label("End of Rigify Preferences") class RigifyName(bpy.types.PropertyGroup): @@ -66,6 +180,8 @@ def register(): bpy.utils.register_class(RigifyName) bpy.utils.register_class(RigifyParameters) bpy.utils.register_class(RigifyArmatureLayer) + bpy.utils.register_class(RigifyPreferences) + bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer) bpy.types.PoseBone.rigify_type = bpy.props.StringProperty(name="Rigify Type", description="Rig type for this bone") bpy.types.PoseBone.rigify_parameters = bpy.props.PointerProperty(type=RigifyParameters) @@ -73,10 +189,17 @@ def register(): bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer) IDStore = bpy.types.WindowManager - IDStore.rigify_collection = bpy.props.EnumProperty(items=rig_lists.col_enum_list, default="All", name="Rigify Active Collection", description="The selected rig collection") + IDStore.rigify_collection = bpy.props.EnumProperty(items=rig_lists.col_enum_list, default="All", + name="Rigify Active Collection", + description="The selected rig collection") + IDStore.rigify_types = bpy.props.CollectionProperty(type=RigifyName) IDStore.rigify_active_type = bpy.props.IntProperty(name="Rigify Active Type", description="The selected rig type") + if (ui and 'legacy' in str(ui)) or bpy.context.user_preferences.addons['rigify'].preferences.legacy_mode: + # update legacy on restart or reload + bpy.context.user_preferences.addons['rigify'].preferences.legacy_mode = True + # Add rig parameters for rig in rig_lists.rig_list: r = utils.get_rig_type(rig) @@ -98,6 +221,7 @@ def unregister(): bpy.utils.unregister_class(RigifyName) bpy.utils.unregister_class(RigifyParameters) bpy.utils.unregister_class(RigifyArmatureLayer) + bpy.utils.unregister_class(RigifyPreferences) metarig_menu.unregister() ui.unregister() diff --git a/rigify/generate.py b/rigify/generate.py index e519c13b1abda6b2482ac8335d21741acd19c342..3fe4e3b8e512a8b631104a1071957fa67f034558 100644 --- a/rigify/generate.py +++ b/rigify/generate.py @@ -32,7 +32,6 @@ from .utils import create_root_widget from .utils import random_id from .utils import copy_attributes from .rig_ui_template import UI_SLIDERS, layers_ui, UI_REGISTER -from .rig_ui_pitchipoy_template import UI_P_SLIDERS, layers_P_ui, UI_P_REGISTER RIG_MODULE = "rigs" @@ -258,11 +257,24 @@ def generate_rig(context, metarig): obj.data.edit_bones[root_bone].roll = 0 bpy.ops.object.mode_set(mode='OBJECT') obj.data.bones[root_bone].layers = ROOT_LAYER + # Put the rig_name in the armature custom properties rna_idprop_ui_prop_get(obj.data, "rig_id", create=True) obj.data["rig_id"] = rig_id t.tick("Create root bone: ") + + # Create Group widget + wgts_group_name = "WGTS" + if wgts_group_name not in scene.objects: + if wgts_group_name in bpy.data.objects: + bpy.data.objects[wgts_group_name].user_clear() + bpy.data.objects.remove(bpy.data.objects[wgts_group_name]) + mesh = bpy.data.meshes.new(wgts_group_name) + wgts_obj = bpy.data.objects.new(wgts_group_name, mesh) + scene.objects.link(wgts_obj) + t.tick("Create main WGTS: ") + #---------------------------------- try: # Collect/initialize all the rigs. @@ -302,10 +314,23 @@ def generate_rig(context, metarig): # Parent any free-floating bones to the root excluding bones with child of constraint. pbones = obj.pose.bones + + + ik_follow_drivers = [] + + if obj.animation_data: + for drv in obj.animation_data.drivers: + for var in drv.driver.variables: + if 'IK_follow' == var.name: + ik_follow_drivers.append(drv.data_path) + noparent_bones = [] for bone in bones: - if 'IK_follow' in pbones[bone].keys(): - noparent_bones += [bone] + # if 'IK_follow' in pbones[bone].keys(): + # noparent_bones += [bone] + for d in ik_follow_drivers: + if bone in d: + noparent_bones += [bone] bpy.ops.object.mode_set(mode='EDIT') for bone in bones: @@ -396,35 +421,18 @@ def generate_rig(context, metarig): print( l.name ) layer_layout += [(l.name, l.row)] - - if isPitchipoy(metarig): - - # Generate the UI Pitchipoy script - if "rig_ui.py" in bpy.data.texts: - script = bpy.data.texts["rig_ui.py"] - script.clear() - else: - script = bpy.data.texts.new("rig_ui.py") - script.write(UI_P_SLIDERS % rig_id) - for s in ui_scripts: - script.write("\n " + s.replace("\n", "\n ") + "\n") - script.write(layers_P_ui(vis_layers, layer_layout)) - script.write(UI_P_REGISTER) - script.use_module = True - + # Generate the UI script + if "rig_ui.py" in bpy.data.texts: + script = bpy.data.texts["rig_ui.py"] + script.clear() else: - # Generate the UI script - if "rig_ui.py" in bpy.data.texts: - script = bpy.data.texts["rig_ui.py"] - script.clear() - else: - script = bpy.data.texts.new("rig_ui.py") - script.write(UI_SLIDERS % rig_id) - for s in ui_scripts: - script.write("\n " + s.replace("\n", "\n ") + "\n") - script.write(layers_ui(vis_layers, layer_layout)) - script.write(UI_REGISTER) - script.use_module = True + script = bpy.data.texts.new("rig_ui.py") + script.write(UI_SLIDERS % rig_id) + for s in ui_scripts: + script.write("\n " + s.replace("\n", "\n ") + "\n") + script.write(layers_ui(vis_layers, layer_layout)) + script.write(UI_REGISTER) + script.use_module = True # Run UI script exec(script.as_string(), {}) @@ -479,13 +487,3 @@ def param_name(param_name, rig_type): """ Get the actual parameter name, sans-rig-type. """ return param_name[len(rig_type) + 1:] - -def isPitchipoy(metarig): - """ Returns True if metarig is type pitchipoy. - """ - pbones=metarig.pose.bones - for pb in pbones: - words = pb.rigify_type.partition('.') - if words[0] == 'pitchipoy': - return True - return False \ No newline at end of file diff --git a/rigify/legacy/__init__.py b/rigify/legacy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6e6f751c7461ba52437bc1d17723b8ba083b1368 --- /dev/null +++ b/rigify/legacy/__init__.py @@ -0,0 +1,103 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +bl_info = { + "name": "Rigify", + "version": (0, 4), + "author": "Nathan Vegdahl", + "blender": (2, 66, 0), + "description": "Automatic rigging from building-block components", + "location": "Armature properties, Bone properties, View3d tools panel, Armature Add menu", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" + "Scripts/Rigging/Rigify", + "tracker_url": "http://github.com/cessen/rigify/issues", + "category": "Rigging"} + + +if "bpy" in locals(): + import importlib + importlib.reload(generate) + importlib.reload(ui) + importlib.reload(utils) + importlib.reload(metarig_menu) + importlib.reload(rig_lists) +else: + from . import utils, rig_lists, generate, ui, metarig_menu + +import bpy + + +class RigifyName(bpy.types.PropertyGroup): + name = bpy.props.StringProperty() + + +class RigifyParameters(bpy.types.PropertyGroup): + name = bpy.props.StringProperty() + + +class RigifyArmatureLayer(bpy.types.PropertyGroup): + name = bpy.props.StringProperty(name="Layer Name", default=" ") + row = bpy.props.IntProperty(name="Layer Row", default=1, min=1, max=32) + + +##### REGISTER ##### + +def register(): + ui.register() + metarig_menu.register() + + bpy.utils.register_class(RigifyName) + bpy.utils.register_class(RigifyParameters) + bpy.utils.register_class(RigifyArmatureLayer) + + bpy.types.PoseBone.rigify_type = bpy.props.StringProperty(name="Rigify Type", description="Rig type for this bone") + bpy.types.PoseBone.rigify_parameters = bpy.props.PointerProperty(type=RigifyParameters) + + bpy.types.Armature.rigify_layers = bpy.props.CollectionProperty(type=RigifyArmatureLayer) + + IDStore = bpy.types.WindowManager + IDStore.rigify_collection = bpy.props.EnumProperty(items=rig_lists.col_enum_list, default="All", name="Rigify Active Collection", description="The selected rig collection") + IDStore.rigify_types = bpy.props.CollectionProperty(type=RigifyName) + IDStore.rigify_active_type = bpy.props.IntProperty(name="Rigify Active Type", description="The selected rig type") + + # Add rig parameters + for rig in rig_lists.rig_list: + r = utils.get_rig_type(rig) + try: + r.add_parameters(RigifyParameters) + except AttributeError: + pass + + +def unregister(): + del bpy.types.PoseBone.rigify_type + del bpy.types.PoseBone.rigify_parameters + + IDStore = bpy.types.WindowManager + del IDStore.rigify_collection + del IDStore.rigify_types + del IDStore.rigify_active_type + + bpy.utils.unregister_class(RigifyName) + bpy.utils.unregister_class(RigifyParameters) + bpy.utils.unregister_class(RigifyArmatureLayer) + + metarig_menu.unregister() + ui.unregister() diff --git a/rigify/legacy/generate.py b/rigify/legacy/generate.py new file mode 100644 index 0000000000000000000000000000000000000000..0536377eff247cfbcacb935f4cfd4a3636dc765c --- /dev/null +++ b/rigify/legacy/generate.py @@ -0,0 +1,482 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +import bpy +import re +import time +import traceback +import sys +from rna_prop_ui import rna_idprop_ui_prop_get + +from .utils import MetarigError, new_bone, get_rig_type +from .utils import ORG_PREFIX, MCH_PREFIX, DEF_PREFIX, WGT_PREFIX, ROOT_NAME, make_original_name +from .utils import RIG_DIR +from .utils import create_root_widget +from .utils import random_id +from .utils import copy_attributes +from .rig_ui_template import UI_SLIDERS, layers_ui, UI_REGISTER +from .rig_ui_pitchipoy_template import UI_P_SLIDERS, layers_P_ui, UI_P_REGISTER + + +RIG_MODULE = "rigs" +ORG_LAYER = [n == 31 for n in range(0, 32)] # Armature layer that original bones should be moved to. +MCH_LAYER = [n == 30 for n in range(0, 32)] # Armature layer that mechanism bones should be moved to. +DEF_LAYER = [n == 29 for n in range(0, 32)] # Armature layer that deformation bones should be moved to. +ROOT_LAYER = [n == 28 for n in range(0, 32)] # Armature layer that root bone should be moved to. + + +class Timer: + def __init__(self): + self.timez = time.time() + + def tick(self, string): + t = time.time() + print(string + "%.3f" % (t - self.timez)) + self.timez = t + + +# TODO: generalize to take a group as input instead of an armature. +def generate_rig(context, metarig): + """ Generates a rig from a metarig. + + """ + t = Timer() + + # Random string with time appended so that + # different rigs don't collide id's + rig_id = random_id(16) + + # Initial configuration + # mode_orig = context.mode # UNUSED + rest_backup = metarig.data.pose_position + metarig.data.pose_position = 'REST' + + bpy.ops.object.mode_set(mode='OBJECT') + + scene = context.scene + + #------------------------------------------ + # Create/find the rig object and set it up + + # Check if the generated rig already exists, so we can + # regenerate in the same object. If not, create a new + # object to generate the rig in. + print("Fetch rig.") + try: + name = metarig["rig_object_name"] + except KeyError: + name = "rig" + + try: + obj = scene.objects[name] + except KeyError: + obj = bpy.data.objects.new(name, bpy.data.armatures.new(name)) + obj.draw_type = 'WIRE' + scene.objects.link(obj) + + obj.data.pose_position = 'POSE' + + # Get rid of anim data in case the rig already existed + print("Clear rig animation data.") + obj.animation_data_clear() + + # Select generated rig object + metarig.select = False + obj.select = True + scene.objects.active = obj + + # Remove all bones from the generated rig armature. + bpy.ops.object.mode_set(mode='EDIT') + for bone in obj.data.edit_bones: + obj.data.edit_bones.remove(bone) + bpy.ops.object.mode_set(mode='OBJECT') + + # Create temporary duplicates for merging + temp_rig_1 = metarig.copy() + temp_rig_1.data = metarig.data.copy() + scene.objects.link(temp_rig_1) + + temp_rig_2 = metarig.copy() + temp_rig_2.data = obj.data + scene.objects.link(temp_rig_2) + + # Select the temp rigs for merging + for objt in scene.objects: + objt.select = False # deselect all objects + temp_rig_1.select = True + temp_rig_2.select = True + scene.objects.active = temp_rig_2 + + # Merge the temporary rigs + bpy.ops.object.join() + + # Delete the second temp rig + bpy.ops.object.delete() + + # Select the generated rig + for objt in scene.objects: + objt.select = False # deselect all objects + obj.select = True + scene.objects.active = obj + + # Copy over bone properties + for bone in metarig.data.bones: + bone_gen = obj.data.bones[bone.name] + + # B-bone stuff + bone_gen.bbone_segments = bone.bbone_segments + bone_gen.bbone_in = bone.bbone_in + bone_gen.bbone_out = bone.bbone_out + + # Copy over the pose_bone properties + for bone in metarig.pose.bones: + bone_gen = obj.pose.bones[bone.name] + + # Rotation mode and transform locks + bone_gen.rotation_mode = bone.rotation_mode + bone_gen.lock_rotation = tuple(bone.lock_rotation) + bone_gen.lock_rotation_w = bone.lock_rotation_w + bone_gen.lock_rotations_4d = bone.lock_rotations_4d + bone_gen.lock_location = tuple(bone.lock_location) + bone_gen.lock_scale = tuple(bone.lock_scale) + + # rigify_type and rigify_parameters + bone_gen.rigify_type = bone.rigify_type + for prop in dir(bone_gen.rigify_parameters): + if (not prop.startswith("_")) \ + and (not prop.startswith("bl_")) \ + and (prop != "rna_type"): + try: + setattr(bone_gen.rigify_parameters, prop, \ + getattr(bone.rigify_parameters, prop)) + except AttributeError: + print("FAILED TO COPY PARAMETER: " + str(prop)) + + # Custom properties + for prop in bone.keys(): + try: + bone_gen[prop] = bone[prop] + except KeyError: + pass + + # Constraints + for con1 in bone.constraints: + con2 = bone_gen.constraints.new(type=con1.type) + copy_attributes(con1, con2) + + # Set metarig target to rig target + if "target" in dir(con2): + if con2.target == metarig: + con2.target = obj + + # Copy drivers + if metarig.animation_data: + for d1 in metarig.animation_data.drivers: + d2 = obj.driver_add(d1.data_path) + copy_attributes(d1, d2) + copy_attributes(d1.driver, d2.driver) + + # Remove default modifiers, variables, etc. + for m in d2.modifiers: + d2.modifiers.remove(m) + for v in d2.driver.variables: + d2.driver.variables.remove(v) + + # Copy modifiers + for m1 in d1.modifiers: + m2 = d2.modifiers.new(type=m1.type) + copy_attributes(m1, m2) + + # Copy variables + for v1 in d1.driver.variables: + v2 = d2.driver.variables.new() + copy_attributes(v1, v2) + for i in range(len(v1.targets)): + copy_attributes(v1.targets[i], v2.targets[i]) + # Switch metarig targets to rig targets + if v2.targets[i].id == metarig: + v2.targets[i].id = obj + + # Mark targets that may need to be altered after rig generation + tar = v2.targets[i] + # If a custom property + if v2.type == 'SINGLE_PROP' \ + and re.match('^pose.bones\["[^"\]]*"\]\["[^"\]]*"\]$', tar.data_path): + tar.data_path = "RIGIFY-" + tar.data_path + + # Copy key frames + for i in range(len(d1.keyframe_points)): + d2.keyframe_points.add() + k1 = d1.keyframe_points[i] + k2 = d2.keyframe_points[i] + copy_attributes(k1, k2) + + t.tick("Duplicate rig: ") + #---------------------------------- + # Make a list of the original bones so we can keep track of them. + original_bones = [bone.name for bone in obj.data.bones] + + # Add the ORG_PREFIX to the original bones. + bpy.ops.object.mode_set(mode='OBJECT') + for i in range(0, len(original_bones)): + obj.data.bones[original_bones[i]].name = make_original_name(original_bones[i]) + original_bones[i] = make_original_name(original_bones[i]) + + # Create a sorted list of the original bones, sorted in the order we're + # going to traverse them for rigging. + # (root-most -> leaf-most, alphabetical) + bones_sorted = [] + for name in original_bones: + bones_sorted += [name] + bones_sorted.sort() # first sort by names + bones_sorted.sort(key=lambda bone: len(obj.pose.bones[bone].parent_recursive)) # then parents before children + + t.tick("Make list of org bones: ") + #---------------------------------- + # Create the root bone. + bpy.ops.object.mode_set(mode='EDIT') + root_bone = new_bone(obj, ROOT_NAME) + obj.data.edit_bones[root_bone].head = (0, 0, 0) + obj.data.edit_bones[root_bone].tail = (0, 1, 0) + obj.data.edit_bones[root_bone].roll = 0 + bpy.ops.object.mode_set(mode='OBJECT') + obj.data.bones[root_bone].layers = ROOT_LAYER + # Put the rig_name in the armature custom properties + rna_idprop_ui_prop_get(obj.data, "rig_id", create=True) + obj.data["rig_id"] = rig_id + + t.tick("Create root bone: ") + #---------------------------------- + try: + # Collect/initialize all the rigs. + rigs = [] + for bone in bones_sorted: + bpy.ops.object.mode_set(mode='EDIT') + rigs += get_bone_rigs(obj, bone) + t.tick("Initialize rigs: ") + + # Generate all the rigs. + ui_scripts = [] + for rig in rigs: + # Go into editmode in the rig armature + bpy.ops.object.mode_set(mode='OBJECT') + context.scene.objects.active = obj + obj.select = True + bpy.ops.object.mode_set(mode='EDIT') + scripts = rig.generate() + if scripts is not None: + ui_scripts += [scripts[0]] + t.tick("Generate rigs: ") + except Exception as e: + # Cleanup if something goes wrong + print("Rigify: failed to generate rig.") + metarig.data.pose_position = rest_backup + obj.data.pose_position = 'POSE' + bpy.ops.object.mode_set(mode='OBJECT') + + # Continue the exception + raise e + + #---------------------------------- + bpy.ops.object.mode_set(mode='OBJECT') + + # Get a list of all the bones in the armature + bones = [bone.name for bone in obj.data.bones] + + # Parent any free-floating bones to the root. + bpy.ops.object.mode_set(mode='EDIT') + for bone in bones: + if obj.data.edit_bones[bone].parent is None: + obj.data.edit_bones[bone].use_connect = False + obj.data.edit_bones[bone].parent = obj.data.edit_bones[root_bone] + bpy.ops.object.mode_set(mode='OBJECT') + + # Lock transforms on all non-control bones + r = re.compile("[A-Z][A-Z][A-Z]-") + for bone in bones: + if r.match(bone): + pb = obj.pose.bones[bone] + pb.lock_location = (True, True, True) + pb.lock_rotation = (True, True, True) + pb.lock_rotation_w = True + pb.lock_scale = (True, True, True) + + # Every bone that has a name starting with "DEF-" make deforming. All the + # others make non-deforming. + for bone in bones: + if obj.data.bones[bone].name.startswith(DEF_PREFIX): + obj.data.bones[bone].use_deform = True + else: + obj.data.bones[bone].use_deform = False + + # Alter marked driver targets + if obj.animation_data: + for d in obj.animation_data.drivers: + for v in d.driver.variables: + for tar in v.targets: + if tar.data_path.startswith("RIGIFY-"): + temp, bone, prop = tuple([x.strip('"]') for x in tar.data_path.split('["')]) + if bone in obj.data.bones \ + and prop in obj.pose.bones[bone].keys(): + tar.data_path = tar.data_path[7:] + else: + tar.data_path = 'pose.bones["%s"]["%s"]' % (make_original_name(bone), prop) + + # Move all the original bones to their layer. + for bone in original_bones: + obj.data.bones[bone].layers = ORG_LAYER + + # Move all the bones with names starting with "MCH-" to their layer. + for bone in bones: + if obj.data.bones[bone].name.startswith(MCH_PREFIX): + obj.data.bones[bone].layers = MCH_LAYER + + # Move all the bones with names starting with "DEF-" to their layer. + for bone in bones: + if obj.data.bones[bone].name.startswith(DEF_PREFIX): + obj.data.bones[bone].layers = DEF_LAYER + + # Create root bone widget + create_root_widget(obj, "root") + + # Assign shapes to bones + # Object's with name WGT-<bone_name> get used as that bone's shape. + for bone in bones: + wgt_name = (WGT_PREFIX + obj.data.bones[bone].name)[:63] # Object names are limited to 63 characters... arg + if wgt_name in context.scene.objects: + # Weird temp thing because it won't let me index by object name + for ob in context.scene.objects: + if ob.name == wgt_name: + obj.pose.bones[bone].custom_shape = ob + break + # This is what it should do: + # obj.pose.bones[bone].custom_shape = context.scene.objects[wgt_name] + # Reveal all the layers with control bones on them + vis_layers = [False for n in range(0, 32)] + for bone in bones: + for i in range(0, 32): + vis_layers[i] = vis_layers[i] or obj.data.bones[bone].layers[i] + for i in range(0, 32): + vis_layers[i] = vis_layers[i] and not (ORG_LAYER[i] or MCH_LAYER[i] or DEF_LAYER[i]) + obj.data.layers = vis_layers + + # Ensure the collection of layer names exists + for i in range(1 + len(metarig.data.rigify_layers), 29): + metarig.data.rigify_layers.add() + + # Create list of layer name/row pairs + layer_layout = [] + for l in metarig.data.rigify_layers: + print( l.name ) + layer_layout += [(l.name, l.row)] + + + if isPitchipoy(metarig): + + # Generate the UI Pitchipoy script + if "rig_ui.py" in bpy.data.texts: + script = bpy.data.texts["rig_ui.py"] + script.clear() + else: + script = bpy.data.texts.new("rig_ui.py") + script.write(UI_P_SLIDERS % rig_id) + for s in ui_scripts: + script.write("\n " + s.replace("\n", "\n ") + "\n") + script.write(layers_P_ui(vis_layers, layer_layout)) + script.write(UI_P_REGISTER) + script.use_module = True + + else: + # Generate the UI script + if "rig_ui.py" in bpy.data.texts: + script = bpy.data.texts["rig_ui.py"] + script.clear() + else: + script = bpy.data.texts.new("rig_ui.py") + script.write(UI_SLIDERS % rig_id) + for s in ui_scripts: + script.write("\n " + s.replace("\n", "\n ") + "\n") + script.write(layers_ui(vis_layers, layer_layout)) + script.write(UI_REGISTER) + script.use_module = True + + # Run UI script + exec(script.as_string(), {}) + + t.tick("The rest: ") + #---------------------------------- + # Deconfigure + bpy.ops.object.mode_set(mode='OBJECT') + metarig.data.pose_position = rest_backup + obj.data.pose_position = 'POSE' + + +def get_bone_rigs(obj, bone_name, halt_on_missing=False): + """ Fetch all the rigs specified on a bone. + """ + rigs = [] + rig_type = obj.pose.bones[bone_name].rigify_type + rig_type = rig_type.replace(" ", "") + + if rig_type == "": + pass + else: + # Gather parameters + params = obj.pose.bones[bone_name].rigify_parameters + + # Get the rig + try: + rig = get_rig_type(rig_type).Rig(obj, bone_name, params) + except ImportError: + message = "Rig Type Missing: python module for type '%s' not found (bone: %s)" % (rig_type, bone_name) + if halt_on_missing: + raise MetarigError(message) + else: + print(message) + print('print_exc():') + traceback.print_exc(file=sys.stdout) + else: + rigs += [rig] + return rigs + + +def param_matches_type(param_name, rig_type): + """ Returns True if the parameter name is consistent with the rig type. + """ + if param_name.rsplit(".", 1)[0] == rig_type: + return True + else: + return False + + +def param_name(param_name, rig_type): + """ Get the actual parameter name, sans-rig-type. + """ + return param_name[len(rig_type) + 1:] + +def isPitchipoy(metarig): + """ Returns True if metarig is type pitchipoy. + """ + pbones=metarig.pose.bones + for pb in pbones: + words = pb.rigify_type.partition('.') + if words[0] == 'pitchipoy': + return True + return False \ No newline at end of file diff --git a/rigify/legacy/metarig_menu.py b/rigify/legacy/metarig_menu.py new file mode 100644 index 0000000000000000000000000000000000000000..4bdf270174d8808f59b7cfe0f5d219000f2d9219 --- /dev/null +++ b/rigify/legacy/metarig_menu.py @@ -0,0 +1,125 @@ +# ##### 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 ##### + +# <pep8 compliant> + +import os +from string import capwords + +import bpy + +from . import utils + + +def get_metarig_list(path): + """ Searches for metarig modules, and returns a list of the + imported modules. + """ + metarigs = [] + MODULE_DIR = os.path.dirname(__file__) + METARIG_DIR_ABS = os.path.join(MODULE_DIR, utils.METARIG_DIR) + SEARCH_DIR_ABS = os.path.join(METARIG_DIR_ABS, path) + files = os.listdir(SEARCH_DIR_ABS) + files.sort() + + for f in files: + # Is it a directory? + if os.path.isdir(os.path.join(SEARCH_DIR_ABS, f)): + continue + elif not f.endswith(".py"): + continue + elif f == "__init__.py": + continue + else: + module_name = f[:-3] + try: + metarigs += [utils.get_metarig_module(module_name)] + except (ImportError): + pass + return metarigs + + +def make_metarig_add_execute(m): + """ Create an execute method for a metarig creation operator. + """ + def execute(self, context): + # Add armature object + bpy.ops.object.armature_add() + obj = context.active_object + obj.name = "metarig" + + # Remove default bone + bpy.ops.object.mode_set(mode='EDIT') + bones = context.active_object.data.edit_bones + bones.remove(bones[0]) + + # Create metarig + m.create(obj) + + bpy.ops.object.mode_set(mode='OBJECT') + return {'FINISHED'} + return execute + + +def make_metarig_menu_func(bl_idname, text): + """ For some reason lambda's don't work for adding multiple menu + items, so we use this instead to generate the functions. + """ + def metarig_menu(self, context): + self.layout.operator(bl_idname, icon='OUTLINER_OB_ARMATURE', text=text) + return metarig_menu + + +# Get the metarig modules +metarigs = get_metarig_list("") + +# Create metarig add Operators +metarig_ops = [] +for m in metarigs: + name = m.__name__.rsplit('.', 1)[1] + + # Dynamically construct an Operator + T = type("Add_" + name + "_Metarig", (bpy.types.Operator,), {}) + T.bl_idname = "object.armature_" + name + "_metarig_add" + T.bl_label = "Add " + name.replace("_", " ").capitalize() + " (metarig)" + T.bl_options = {'REGISTER', 'UNDO'} + T.execute = make_metarig_add_execute(m) + + metarig_ops.append((T, name)) + +# Create menu functions +menu_funcs = [] +for mop, name in metarig_ops: + text = capwords(name.replace("_", " ")) + " (Meta-Rig)" + menu_funcs += [make_metarig_menu_func(mop.bl_idname, text)] + + +def register(): + for mop, name in metarig_ops: + bpy.utils.register_class(mop) + + for mf in menu_funcs: + bpy.types.INFO_MT_armature_add.append(mf) + + +def unregister(): + for mop, name in metarig_ops: + bpy.utils.unregister_class(mop) + + for mf in menu_funcs: + bpy.types.INFO_MT_armature_add.remove(mf) diff --git a/rigify/rigs/biped/__init__.py b/rigify/legacy/metarigs/__init__.py similarity index 100% rename from rigify/rigs/biped/__init__.py rename to rigify/legacy/metarigs/__init__.py diff --git a/rigify/legacy/metarigs/human.py b/rigify/legacy/metarigs/human.py new file mode 100644 index 0000000000000000000000000000000000000000..7adc03d7e74da57e196bf5746a253d773a56cefc --- /dev/null +++ b/rigify/legacy/metarigs/human.py @@ -0,0 +1,1200 @@ +# ##### 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 ##### + +# <pep8 compliant> + +import bpy + +def create(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + for i in range(28): + arm.rigify_layers.add() + + arm.rigify_layers[0].name = "head" + arm.rigify_layers[0].row = 1 + arm.rigify_layers[1].name = " " + arm.rigify_layers[1].row = 1 + arm.rigify_layers[2].name = "Torso" + arm.rigify_layers[2].row = 2 + arm.rigify_layers[3].name = " " + arm.rigify_layers[3].row = 1 + arm.rigify_layers[4].name = "Fingers" + arm.rigify_layers[4].row = 3 + arm.rigify_layers[5].name = "(Tweak)" + arm.rigify_layers[5].row = 3 + arm.rigify_layers[6].name = "Arm.L (FK)" + arm.rigify_layers[6].row = 4 + arm.rigify_layers[7].name = "Arm.L (IK)" + arm.rigify_layers[7].row = 5 + arm.rigify_layers[8].name = "Arm.L (Tweak)" + arm.rigify_layers[8].row = 6 + arm.rigify_layers[9].name = "Arm.R (FK)" + arm.rigify_layers[9].row = 4 + arm.rigify_layers[10].name = "Arm.R (IK)" + arm.rigify_layers[10].row = 5 + arm.rigify_layers[11].name = "Arm.R (Tweak)" + arm.rigify_layers[11].row = 6 + arm.rigify_layers[12].name = "Leg.L (FK)" + arm.rigify_layers[12].row = 7 + arm.rigify_layers[13].name = "Leg.L (IK)" + arm.rigify_layers[13].row = 8 + arm.rigify_layers[14].name = "Leg.L (Tweak)" + arm.rigify_layers[14].row = 9 + arm.rigify_layers[15].name = "Leg.R (FK)" + arm.rigify_layers[15].row = 7 + arm.rigify_layers[16].name = "Leg.R (IK)" + arm.rigify_layers[16].row = 8 + arm.rigify_layers[17].name = "Leg.R (Tweak)" + arm.rigify_layers[17].row = 9 + arm.rigify_layers[18].name = " " + arm.rigify_layers[18].row = 1 + arm.rigify_layers[19].name = " " + arm.rigify_layers[19].row = 1 + arm.rigify_layers[20].name = " " + arm.rigify_layers[20].row = 1 + arm.rigify_layers[21].name = " " + arm.rigify_layers[21].row = 1 + arm.rigify_layers[22].name = " " + arm.rigify_layers[22].row = 1 + arm.rigify_layers[23].name = " " + arm.rigify_layers[23].row = 1 + arm.rigify_layers[24].name = " " + arm.rigify_layers[24].row = 1 + arm.rigify_layers[25].name = " " + arm.rigify_layers[25].row = 1 + arm.rigify_layers[26].name = " " + arm.rigify_layers[26].row = 1 + arm.rigify_layers[27].name = " " + arm.rigify_layers[27].row = 1 + + bones = {} + + bone = arm.edit_bones.new('hips') + bone.head[:] = 0.0000, 0.0552, 1.0099 + bone.tail[:] = 0.0000, 0.0172, 1.1837 + bone.roll = 0.0000 + bone.use_connect = False + bones['hips'] = bone.name + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 0.0172, 1.1837 + bone.tail[:] = 0.0000, 0.0004, 1.3418 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['hips']] + bones['spine'] = bone.name + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.0980, 0.0124, 1.0720 + bone.tail[:] = 0.0980, -0.0286, 0.5372 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hips']] + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('thigh.R') + bone.head[:] = -0.0980, 0.0124, 1.0720 + bone.tail[:] = -0.0980, -0.0286, 0.5372 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hips']] + bones['thigh.R'] = bone.name + bone = arm.edit_bones.new('chest') + bone.head[:] = 0.0000, 0.0004, 1.3418 + bone.tail[:] = 0.0000, 0.0114, 1.6582 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['chest'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.0980, -0.0286, 0.5372 + bone.tail[:] = 0.0980, 0.0162, 0.0852 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('shin.R') + bone.head[:] = -0.0980, -0.0286, 0.5372 + bone.tail[:] = -0.0980, 0.0162, 0.0852 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.R']] + bones['shin.R'] = bone.name + bone = arm.edit_bones.new('neck') + bone.head[:] = 0.0000, 0.0114, 1.6582 + bone.tail[:] = 0.0000, -0.0247, 1.7813 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['chest']] + bones['neck'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0183, -0.0684, 1.6051 + bone.tail[:] = 0.1694, 0.0205, 1.6050 + bone.roll = 0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['chest']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0183, -0.0684, 1.6051 + bone.tail[:] = -0.1694, 0.0205, 1.6050 + bone.roll = -0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['chest']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.0980, 0.0162, 0.0852 + bone.tail[:] = 0.0980, -0.0934, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('heel.L') + bone.head[:] = 0.0980, 0.0162, 0.0852 + bone.tail[:] = 0.0980, 0.0882, -0.0000 + bone.roll = -3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['heel.L'] = bone.name + bone = arm.edit_bones.new('foot.R') + bone.head[:] = -0.0980, 0.0162, 0.0852 + bone.tail[:] = -0.0980, -0.0934, 0.0167 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['foot.R'] = bone.name + bone = arm.edit_bones.new('heel.R') + bone.head[:] = -0.0980, 0.0162, 0.0852 + bone.tail[:] = -0.0980, 0.0882, -0.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.R']] + bones['heel.R'] = bone.name + bone = arm.edit_bones.new('head') + bone.head[:] = 0.0000, -0.0247, 1.7813 + bone.tail[:] = 0.0000, -0.0247, 1.9347 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['neck']] + bones['head'] = bone.name + bone = arm.edit_bones.new('upper_arm.L') + bone.head[:] = 0.1953, 0.0267, 1.5846 + bone.tail[:] = 0.4424, 0.0885, 1.4491 + bone.roll = 2.0691 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('upper_arm.R') + bone.head[:] = -0.1953, 0.0267, 1.5846 + bone.tail[:] = -0.4424, 0.0885, 1.4491 + bone.roll = -2.0691 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['upper_arm.R'] = bone.name + bone = arm.edit_bones.new('toe.L') + bone.head[:] = 0.0980, -0.0934, 0.0167 + bone.tail[:] = 0.0980, -0.1606, 0.0167 + bone.roll = -0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['toe.L'] = bone.name + bone = arm.edit_bones.new('heel.02.L') + bone.head[:] = 0.0600, 0.0000, 0.0000 + bone.tail[:] = 0.1400, 0.0000, 0.0000 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['heel.L']] + bones['heel.02.L'] = bone.name + bone = arm.edit_bones.new('toe.R') + bone.head[:] = -0.0980, -0.0934, 0.0167 + bone.tail[:] = -0.0980, -0.1606, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.R']] + bones['toe.R'] = bone.name + bone = arm.edit_bones.new('heel.02.R') + bone.head[:] = -0.0600, 0.0000, 0.0000 + bone.tail[:] = -0.1400, 0.0000, 0.0000 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['heel.R']] + bones['heel.02.R'] = bone.name + bone = arm.edit_bones.new('forearm.L') + bone.head[:] = 0.4424, 0.0885, 1.4491 + bone.tail[:] = 0.6594, 0.0492, 1.3061 + bone.roll = 2.1459 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.L']] + bones['forearm.L'] = bone.name + bone = arm.edit_bones.new('forearm.R') + bone.head[:] = -0.4424, 0.0885, 1.4491 + bone.tail[:] = -0.6594, 0.0492, 1.3061 + bone.roll = -2.1459 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['upper_arm.R']] + bones['forearm.R'] = bone.name + bone = arm.edit_bones.new('hand.L') + bone.head[:] = 0.6594, 0.0492, 1.3061 + bone.tail[:] = 0.7234, 0.0412, 1.2585 + bone.roll = -2.4946 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.L']] + bones['hand.L'] = bone.name + bone = arm.edit_bones.new('hand.R') + bone.head[:] = -0.6594, 0.0492, 1.3061 + bone.tail[:] = -0.7234, 0.0412, 1.2585 + bone.roll = 2.4946 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['forearm.R']] + bones['hand.R'] = bone.name + bone = arm.edit_bones.new('palm.01.L') + bone.head[:] = 0.6921, 0.0224, 1.2882 + bone.tail[:] = 0.7464, 0.0051, 1.2482 + bone.roll = -2.4928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.L']] + bones['palm.01.L'] = bone.name + bone = arm.edit_bones.new('palm.02.L') + bone.head[:] = 0.6970, 0.0389, 1.2877 + bone.tail[:] = 0.7518, 0.0277, 1.2487 + bone.roll = -2.5274 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.L']] + bones['palm.02.L'] = bone.name + bone = arm.edit_bones.new('palm.03.L') + bone.head[:] = 0.6963, 0.0545, 1.2874 + bone.tail[:] = 0.7540, 0.0521, 1.2482 + bone.roll = -2.5843 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.L']] + bones['palm.03.L'] = bone.name + bone = arm.edit_bones.new('palm.04.L') + bone.head[:] = 0.6929, 0.0696, 1.2871 + bone.tail[:] = 0.7528, 0.0763, 1.2428 + bone.roll = -2.5155 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.L']] + bones['palm.04.L'] = bone.name + bone = arm.edit_bones.new('palm.01.R') + bone.head[:] = -0.6921, 0.0224, 1.2882 + bone.tail[:] = -0.7464, 0.0051, 1.2482 + bone.roll = 2.4928 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.R']] + bones['palm.01.R'] = bone.name + bone = arm.edit_bones.new('palm.02.R') + bone.head[:] = -0.6970, 0.0389, 1.2877 + bone.tail[:] = -0.7518, 0.0277, 1.2487 + bone.roll = 2.5274 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.R']] + bones['palm.02.R'] = bone.name + bone = arm.edit_bones.new('palm.03.R') + bone.head[:] = -0.6963, 0.0544, 1.2874 + bone.tail[:] = -0.7540, 0.0521, 1.2482 + bone.roll = 2.5843 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.R']] + bones['palm.03.R'] = bone.name + bone = arm.edit_bones.new('palm.04.R') + bone.head[:] = -0.6929, 0.0696, 1.2871 + bone.tail[:] = -0.7528, 0.0763, 1.2428 + bone.roll = 2.5155 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['hand.R']] + bones['palm.04.R'] = bone.name + bone = arm.edit_bones.new('f_index.01.L') + bone.head[:] = 0.7464, 0.0051, 1.2482 + bone.tail[:] = 0.7718, 0.0013, 1.2112 + bone.roll = -2.0315 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.01.L']] + bones['f_index.01.L'] = bone.name + bone = arm.edit_bones.new('thumb.01.L') + bone.head[:] = 0.6705, 0.0214, 1.2738 + bone.tail[:] = 0.6857, 0.0015, 1.2404 + bone.roll = -0.1587 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.01.L']] + bones['thumb.01.L'] = bone.name + bone = arm.edit_bones.new('f_middle.01.L') + bone.head[:] = 0.7518, 0.0277, 1.2487 + bone.tail[:] = 0.7762, 0.0234, 1.2058 + bone.roll = -2.0067 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.02.L']] + bones['f_middle.01.L'] = bone.name + bone = arm.edit_bones.new('f_ring.01.L') + bone.head[:] = 0.7540, 0.0521, 1.2482 + bone.tail[:] = 0.7715, 0.0499, 1.2070 + bone.roll = -2.0082 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.03.L']] + bones['f_ring.01.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.01.L') + bone.head[:] = 0.7528, 0.0763, 1.2428 + bone.tail[:] = 0.7589, 0.0765, 1.2156 + bone.roll = -1.9749 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.04.L']] + bones['f_pinky.01.L'] = bone.name + bone = arm.edit_bones.new('f_index.01.R') + bone.head[:] = -0.7464, 0.0051, 1.2482 + bone.tail[:] = -0.7718, 0.0012, 1.2112 + bone.roll = 2.0315 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.01.R']] + bones['f_index.01.R'] = bone.name + bone = arm.edit_bones.new('thumb.01.R') + bone.head[:] = -0.6705, 0.0214, 1.2738 + bone.tail[:] = -0.6857, 0.0015, 1.2404 + bone.roll = 0.1587 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['palm.01.R']] + bones['thumb.01.R'] = bone.name + bone = arm.edit_bones.new('f_middle.01.R') + bone.head[:] = -0.7518, 0.0277, 1.2487 + bone.tail[:] = -0.7762, 0.0233, 1.2058 + bone.roll = 2.0067 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.02.R']] + bones['f_middle.01.R'] = bone.name + bone = arm.edit_bones.new('f_ring.01.R') + bone.head[:] = -0.7540, 0.0521, 1.2482 + bone.tail[:] = -0.7715, 0.0499, 1.2070 + bone.roll = 2.0082 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.03.R']] + bones['f_ring.01.R'] = bone.name + bone = arm.edit_bones.new('f_pinky.01.R') + bone.head[:] = -0.7528, 0.0763, 1.2428 + bone.tail[:] = -0.7589, 0.0765, 1.2156 + bone.roll = 1.9749 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['palm.04.R']] + bones['f_pinky.01.R'] = bone.name + bone = arm.edit_bones.new('f_index.02.L') + bone.head[:] = 0.7718, 0.0013, 1.2112 + bone.tail[:] = 0.7840, -0.0003, 1.1858 + bone.roll = -1.8799 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.01.L']] + bones['f_index.02.L'] = bone.name + bone = arm.edit_bones.new('thumb.02.L') + bone.head[:] = 0.6857, 0.0015, 1.2404 + bone.tail[:] = 0.7056, -0.0057, 1.2145 + bone.roll = -0.4798 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thumb.01.L']] + bones['thumb.02.L'] = bone.name + bone = arm.edit_bones.new('f_middle.02.L') + bone.head[:] = 0.7762, 0.0234, 1.2058 + bone.tail[:] = 0.7851, 0.0218, 1.1749 + bone.roll = -1.8283 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.01.L']] + bones['f_middle.02.L'] = bone.name + bone = arm.edit_bones.new('f_ring.02.L') + bone.head[:] = 0.7715, 0.0499, 1.2070 + bone.tail[:] = 0.7794, 0.0494, 1.1762 + bone.roll = -1.8946 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.01.L']] + bones['f_ring.02.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.02.L') + bone.head[:] = 0.7589, 0.0765, 1.2156 + bone.tail[:] = 0.7618, 0.0770, 1.1932 + 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_index.02.R') + bone.head[:] = -0.7718, 0.0012, 1.2112 + bone.tail[:] = -0.7840, -0.0003, 1.1858 + bone.roll = 1.8799 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.01.R']] + bones['f_index.02.R'] = bone.name + bone = arm.edit_bones.new('thumb.02.R') + bone.head[:] = -0.6857, 0.0015, 1.2404 + bone.tail[:] = -0.7056, -0.0057, 1.2145 + bone.roll = 0.4798 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thumb.01.R']] + bones['thumb.02.R'] = bone.name + bone = arm.edit_bones.new('f_middle.02.R') + bone.head[:] = -0.7762, 0.0233, 1.2058 + bone.tail[:] = -0.7851, 0.0218, 1.1749 + bone.roll = 1.8283 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.01.R']] + bones['f_middle.02.R'] = bone.name + bone = arm.edit_bones.new('f_ring.02.R') + bone.head[:] = -0.7715, 0.0499, 1.2070 + bone.tail[:] = -0.7794, 0.0494, 1.1762 + bone.roll = 1.8946 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.01.R']] + bones['f_ring.02.R'] = bone.name + bone = arm.edit_bones.new('f_pinky.02.R') + bone.head[:] = -0.7589, 0.0765, 1.2156 + bone.tail[:] = -0.7618, 0.0770, 1.1932 + bone.roll = 1.9059 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.01.R']] + bones['f_pinky.02.R'] = bone.name + bone = arm.edit_bones.new('f_index.03.L') + bone.head[:] = 0.7840, -0.0003, 1.1858 + bone.tail[:] = 0.7892, 0.0006, 1.1636 + bone.roll = -1.6760 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.02.L']] + bones['f_index.03.L'] = bone.name + bone = arm.edit_bones.new('thumb.03.L') + bone.head[:] = 0.7056, -0.0057, 1.2145 + bone.tail[:] = 0.7194, -0.0098, 1.1995 + bone.roll = -0.5826 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thumb.02.L']] + bones['thumb.03.L'] = bone.name + bone = arm.edit_bones.new('f_middle.03.L') + bone.head[:] = 0.7851, 0.0218, 1.1749 + bone.tail[:] = 0.7888, 0.0216, 1.1525 + bone.roll = -1.7483 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.02.L']] + bones['f_middle.03.L'] = bone.name + bone = arm.edit_bones.new('f_ring.03.L') + bone.head[:] = 0.7794, 0.0494, 1.1762 + bone.tail[:] = 0.7781, 0.0498, 1.1577 + bone.roll = -1.6582 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.02.L']] + bones['f_ring.03.L'] = bone.name + bone = arm.edit_bones.new('f_pinky.03.L') + bone.head[:] = 0.7618, 0.0770, 1.1932 + bone.tail[:] = 0.7611, 0.0772, 1.1782 + 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 + bone = arm.edit_bones.new('f_index.03.R') + bone.head[:] = -0.7840, -0.0003, 1.1858 + bone.tail[:] = -0.7892, 0.0006, 1.1636 + bone.roll = 1.6760 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_index.02.R']] + bones['f_index.03.R'] = bone.name + bone = arm.edit_bones.new('thumb.03.R') + bone.head[:] = -0.7056, -0.0057, 1.2145 + bone.tail[:] = -0.7194, -0.0098, 1.1995 + bone.roll = 0.5826 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thumb.02.R']] + bones['thumb.03.R'] = bone.name + bone = arm.edit_bones.new('f_middle.03.R') + bone.head[:] = -0.7851, 0.0218, 1.1749 + bone.tail[:] = -0.7888, 0.0216, 1.1525 + bone.roll = 1.7483 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_middle.02.R']] + bones['f_middle.03.R'] = bone.name + bone = arm.edit_bones.new('f_ring.03.R') + bone.head[:] = -0.7794, 0.0494, 1.1762 + bone.tail[:] = -0.7781, 0.0498, 1.1577 + bone.roll = 1.6582 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_ring.02.R']] + bones['f_ring.03.R'] = bone.name + bone = arm.edit_bones.new('f_pinky.03.R') + bone.head[:] = -0.7618, 0.0770, 1.1932 + bone.tail[:] = -0.7611, 0.0772, 1.1782 + bone.roll = 1.7639 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['f_pinky.02.R']] + bones['f_pinky.03.R'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['hips']] + pbone.rigify_type = 'spine' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [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, False, False] + try: + pbone.rigify_parameters.chain_bone_controls = "1, 2, 3" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = 'biped.leg' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, 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] + 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, False, False, False, False, False, True, 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, False, False, False, False, False, True, 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['thigh.R']] + pbone.rigify_type = 'biped.leg' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [False, False, False, False, False, False, 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] + 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, False, False, False, False, False, False, False, False, True, 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, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['chest']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['shin.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.bone.layers = [False, False, False, 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] + pbone = obj.pose.bones[bones['shin.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.bone.layers = [False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['neck']] + pbone.rigify_type = 'neck_short' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.copy' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.copy' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['foot.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.bone.layers = [False, False, False, 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] + pbone = obj.pose.bones[bones['heel.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.bone.layers = [False, False, False, 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] + pbone = obj.pose.bones[bones['foot.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.bone.layers = [False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['heel.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.bone.layers = [False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['head']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'biped.arm' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [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, False, False] + try: + pbone.rigify_parameters.separate_ik_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.ik_layers = [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, 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, 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['upper_arm.R']] + pbone.rigify_type = 'biped.arm' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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, False, False, True, 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, False, False, True, 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['toe.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.bone.layers = [False, False, False, 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] + pbone = obj.pose.bones[bones['heel.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.bone.layers = [False, False, False, 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] + pbone = obj.pose.bones[bones['toe.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.bone.layers = [False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['heel.02.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.bone.layers = [False, False, False, False, False, False, 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] + 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.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['forearm.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.bone.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] + 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' + pbone.bone.layers = [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, False, False] + pbone = obj.pose.bones[bones['hand.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.bone.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] + pbone = obj.pose.bones[bones['palm.01.L']] + pbone.rigify_type = 'palm' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.02.L']] + pbone.rigify_type = '' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.03.L']] + pbone.rigify_type = '' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.04.L']] + pbone.rigify_type = '' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, True, True) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.01.R']] + 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' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.02.R']] + 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.bone.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] + pbone = obj.pose.bones[bones['palm.03.R']] + 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.bone.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] + pbone = obj.pose.bones[bones['palm.04.R']] + 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.bone.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] + pbone = obj.pose.bones[bones['f_index.01.L']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['thumb.01.L']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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.separate_extra_layers = True + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.01.L']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_ring.01.L']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_pinky.01.L']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_index.01.R']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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.separate_extra_layers = True + except AttributeError: + pass + pbone = obj.pose.bones[bones['thumb.01.R']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_middle.01.R']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_ring.01.R']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_pinky.01.R']] + pbone.rigify_type = 'finger' + pbone.lock_location = (True, True, True) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.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] + 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 + pbone = obj.pose.bones[bones['f_index.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.bone.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] + pbone = obj.pose.bones[bones['thumb.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.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.bone.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] + 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.bone.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] + pbone = obj.pose.bones[bones['f_index.02.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.bone.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] + pbone = obj.pose.bones[bones['thumb.02.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.02.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.02.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.bone.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] + pbone = obj.pose.bones[bones['f_pinky.02.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.bone.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] + pbone = obj.pose.bones[bones['f_index.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['thumb.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_middle.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_ring.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' + pbone.bone.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] + 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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_index.03.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.bone.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] + pbone = obj.pose.bones[bones['thumb.03.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.03.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.03.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.bone.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] + pbone = obj.pose.bones[bones['f_pinky.03.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.bone.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] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0, 2, 4, 6, 9, 12, 15]) for x in range(32)] + +if __name__ == "__main__": + create(bpy.context.active_object) diff --git a/rigify/metarigs/pitchipoy_human.py b/rigify/legacy/metarigs/pitchipoy_human.py similarity index 100% rename from rigify/metarigs/pitchipoy_human.py rename to rigify/legacy/metarigs/pitchipoy_human.py diff --git a/rigify/legacy/rig_lists.py b/rigify/legacy/rig_lists.py new file mode 100644 index 0000000000000000000000000000000000000000..8de8528e6a9a9577170f422e8773bedd7dd1d7b1 --- /dev/null +++ b/rigify/legacy/rig_lists.py @@ -0,0 +1,78 @@ +#====================== 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 os + +from . import utils + + +def get_rig_list(path): + """ Recursively searches for rig types, and returns a list. + """ + rigs = [] + MODULE_DIR = os.path.dirname(__file__) + RIG_DIR_ABS = os.path.join(MODULE_DIR, utils.RIG_DIR) + SEARCH_DIR_ABS = os.path.join(RIG_DIR_ABS, path) + files = os.listdir(SEARCH_DIR_ABS) + files.sort() + + for f in files: + is_dir = os.path.isdir(os.path.join(SEARCH_DIR_ABS, f)) # Whether the file is a directory + + # Stop cases + if f[0] in [".", "_"]: + continue + if f.count(".") >= 2 or (is_dir and "." in f): + print("Warning: %r, filename contains a '.', skipping" % os.path.join(SEARCH_DIR_ABS, f)) + continue + + if is_dir: + # Check directories + module_name = os.path.join(path, f).replace(os.sep, ".") + rig = utils.get_rig_type(module_name) + # Check if it's a rig itself + if hasattr(rig, "Rig"): + rigs += [f] + else: + # Check for sub-rigs + ls = get_rig_list(os.path.join(path, f, "")) # "" adds a final slash + rigs.extend(["%s.%s" % (f, l) for l in ls]) + elif f.endswith(".py"): + # Check straight-up python files + t = f[:-3] + module_name = os.path.join(path, t).replace(os.sep, ".") + rig = utils.get_rig_type(module_name) + if hasattr(rig, "Rig"): + rigs += [t] + rigs.sort() + return rigs + + +def get_collection_list(rig_list): + collection_list = [] + for r in rig_list: + a = r.split(".") + if len(a) >= 2 and a[0] not in collection_list: + collection_list += [a[0]] + return collection_list + + +# Public variables +rig_list = get_rig_list("") +collection_list = get_collection_list(rig_list) +col_enum_list = [("All", "All", ""), ("None", "None", "")] + [(c, c, "") for c in collection_list] diff --git a/rigify/rig_ui_pitchipoy_template.py b/rigify/legacy/rig_ui_pitchipoy_template.py old mode 100755 new mode 100644 similarity index 98% rename from rigify/rig_ui_pitchipoy_template.py rename to rigify/legacy/rig_ui_pitchipoy_template.py index 0c9dc1bd1bd6fbdfdbb24024f0e869dcbafddcef..5817f9c5854a6ee9140557ef347bc24406ea0267 --- a/rigify/rig_ui_pitchipoy_template.py +++ b/rigify/legacy/rig_ui_pitchipoy_template.py @@ -538,7 +538,7 @@ class Rigify_Arm_FK2IK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo @@ -568,7 +568,7 @@ class Rigify_Arm_IK2FK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo @@ -599,7 +599,7 @@ class Rigify_Leg_FK2IK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo @@ -632,7 +632,7 @@ class Rigify_Leg_IK2FK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo diff --git a/rigify/legacy/rig_ui_template.py b/rigify/legacy/rig_ui_template.py new file mode 100644 index 0000000000000000000000000000000000000000..717410da7b14ab789eda7aa4af13b5a426614bea --- /dev/null +++ b/rigify/legacy/rig_ui_template.py @@ -0,0 +1,608 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +UI_SLIDERS = ''' +import bpy +from mathutils import Matrix, Vector +from math import acos, pi + +rig_id = "%s" + + +############################ +## Math utility functions ## +############################ + +def perpendicular_vector(v): + """ Returns a vector that is perpendicular to the one given. + The returned vector is _not_ guaranteed to be normalized. + """ + # Create a vector that is not aligned with v. + # It doesn't matter what vector. Just any vector + # that's guaranteed to not be pointing in the same + # direction. + if abs(v[0]) < abs(v[1]): + tv = Vector((1,0,0)) + else: + tv = Vector((0,1,0)) + + # Use cross prouct to generate a vector perpendicular to + # both tv and (more importantly) v. + return v.cross(tv) + + +def rotation_difference(mat1, mat2): + """ Returns the shortest-path rotational difference between two + matrices. + """ + q1 = mat1.to_quaternion() + q2 = mat2.to_quaternion() + angle = acos(min(1,max(-1,q1.dot(q2)))) * 2 + if angle > pi: + angle = -angle + (2*pi) + return angle + + +######################################### +## "Visual Transform" helper functions ## +######################################### + +def get_pose_matrix_in_other_space(mat, pose_bone): + """ Returns the transform matrix relative to pose_bone's current + transform space. In other words, presuming that mat is in + armature space, slapping the returned matrix onto pose_bone + should give it the armature-space transforms of mat. + TODO: try to handle cases with axis-scaled parents better. + """ + rest = pose_bone.bone.matrix_local.copy() + rest_inv = rest.inverted() + if pose_bone.parent: + par_mat = pose_bone.parent.matrix.copy() + par_inv = par_mat.inverted() + par_rest = pose_bone.parent.bone.matrix_local.copy() + else: + par_mat = Matrix() + par_inv = Matrix() + par_rest = Matrix() + + # Get matrix in bone's current transform space + smat = rest_inv * (par_rest * (par_inv * mat)) + + # Compensate for non-local location + #if not pose_bone.bone.use_local_location: + # loc = smat.to_translation() * (par_rest.inverted() * rest).to_quaternion() + # smat.translation = loc + + return smat + + +def get_local_pose_matrix(pose_bone): + """ Returns the local transform matrix of the given pose bone. + """ + return get_pose_matrix_in_other_space(pose_bone.matrix, pose_bone) + + +def set_pose_translation(pose_bone, mat): + """ Sets the pose bone's translation to the same translation as the given matrix. + Matrix should be given in bone's local space. + """ + if pose_bone.bone.use_local_location is True: + pose_bone.location = mat.to_translation() + else: + loc = mat.to_translation() + + rest = pose_bone.bone.matrix_local.copy() + if pose_bone.bone.parent: + par_rest = pose_bone.bone.parent.matrix_local.copy() + else: + par_rest = Matrix() + + q = (par_rest.inverted() * rest).to_quaternion() + pose_bone.location = q * loc + + +def set_pose_rotation(pose_bone, mat): + """ Sets the pose bone's rotation to the same rotation as the given matrix. + Matrix should be given in bone's local space. + """ + q = mat.to_quaternion() + + if pose_bone.rotation_mode == 'QUATERNION': + pose_bone.rotation_quaternion = q + elif pose_bone.rotation_mode == 'AXIS_ANGLE': + pose_bone.rotation_axis_angle[0] = q.angle + pose_bone.rotation_axis_angle[1] = q.axis[0] + pose_bone.rotation_axis_angle[2] = q.axis[1] + pose_bone.rotation_axis_angle[3] = q.axis[2] + else: + pose_bone.rotation_euler = q.to_euler(pose_bone.rotation_mode) + + +def set_pose_scale(pose_bone, mat): + """ Sets the pose bone's scale to the same scale as the given matrix. + Matrix should be given in bone's local space. + """ + pose_bone.scale = mat.to_scale() + + +def match_pose_translation(pose_bone, target_bone): + """ Matches pose_bone's visual translation to target_bone's visual + translation. + This function assumes you are in pose mode on the relevant armature. + """ + mat = get_pose_matrix_in_other_space(target_bone.matrix, pose_bone) + set_pose_translation(pose_bone, mat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + +def match_pose_rotation(pose_bone, target_bone): + """ Matches pose_bone's visual rotation to target_bone's visual + rotation. + This function assumes you are in pose mode on the relevant armature. + """ + mat = get_pose_matrix_in_other_space(target_bone.matrix, pose_bone) + set_pose_rotation(pose_bone, mat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + +def match_pose_scale(pose_bone, target_bone): + """ Matches pose_bone's visual scale to target_bone's visual + scale. + This function assumes you are in pose mode on the relevant armature. + """ + mat = get_pose_matrix_in_other_space(target_bone.matrix, pose_bone) + set_pose_scale(pose_bone, mat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + +############################## +## IK/FK snapping functions ## +############################## + +def match_pole_target(ik_first, ik_last, pole, match_bone, length): + """ Places an IK chain's pole target to match ik_first's + transforms to match_bone. All bones should be given as pose bones. + You need to be in pose mode on the relevant armature object. + ik_first: first bone in the IK chain + ik_last: last bone in the IK chain + pole: pole target bone for the IK chain + match_bone: bone to match ik_first to (probably first bone in a matching FK chain) + length: distance pole target should be placed from the chain center + """ + a = ik_first.matrix.to_translation() + b = ik_last.matrix.to_translation() + ik_last.vector + + # Vector from the head of ik_first to the + # tip of ik_last + ikv = b - a + + # Get a vector perpendicular to ikv + pv = perpendicular_vector(ikv).normalized() * length + + def set_pole(pvi): + """ Set pole target's position based on a vector + from the arm center line. + """ + # Translate pvi into armature space + ploc = a + (ikv/2) + pvi + + # Set pole target to location + mat = get_pose_matrix_in_other_space(Matrix.Translation(ploc), pole) + set_pose_translation(pole, mat) + + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + set_pole(pv) + + # Get the rotation difference between ik_first and match_bone + angle = rotation_difference(ik_first.matrix, match_bone.matrix) + + # Try compensating for the rotation difference in both directions + pv1 = Matrix.Rotation(angle, 4, ikv) * pv + set_pole(pv1) + ang1 = rotation_difference(ik_first.matrix, match_bone.matrix) + + pv2 = Matrix.Rotation(-angle, 4, ikv) * pv + set_pole(pv2) + ang2 = rotation_difference(ik_first.matrix, match_bone.matrix) + + # Do the one with the smaller angle + if ang1 < ang2: + set_pole(pv1) + + +def fk2ik_arm(obj, fk, ik): + """ Matches the fk bones in an arm rig to the ik bones. + obj: armature object + fk: list of fk bone names + ik: list of ik bone names + """ + uarm = obj.pose.bones[fk[0]] + farm = obj.pose.bones[fk[1]] + hand = obj.pose.bones[fk[2]] + uarmi = obj.pose.bones[ik[0]] + farmi = obj.pose.bones[ik[1]] + handi = obj.pose.bones[ik[2]] + + # Stretch + if handi['auto_stretch'] == 0.0: + uarm['stretch_length'] = handi['stretch_length'] + else: + diff = (uarmi.vector.length + farmi.vector.length) / (uarm.vector.length + farm.vector.length) + uarm['stretch_length'] *= diff + + # Upper arm position + match_pose_rotation(uarm, uarmi) + match_pose_scale(uarm, uarmi) + + # Forearm position + match_pose_rotation(farm, farmi) + match_pose_scale(farm, farmi) + + # Hand position + match_pose_rotation(hand, handi) + match_pose_scale(hand, handi) + + +def ik2fk_arm(obj, fk, ik): + """ Matches the ik bones in an arm rig to the fk bones. + obj: armature object + fk: list of fk bone names + ik: list of ik bone names + """ + uarm = obj.pose.bones[fk[0]] + farm = obj.pose.bones[fk[1]] + hand = obj.pose.bones[fk[2]] + uarmi = obj.pose.bones[ik[0]] + farmi = obj.pose.bones[ik[1]] + handi = obj.pose.bones[ik[2]] + pole = obj.pose.bones[ik[3]] + + # Stretch + handi['stretch_length'] = uarm['stretch_length'] + + # Hand position + match_pose_translation(handi, hand) + match_pose_rotation(handi, hand) + match_pose_scale(handi, hand) + + # Pole target position + match_pole_target(uarmi, farmi, pole, uarm, (uarmi.length + farmi.length)) + + +def fk2ik_leg(obj, fk, ik): + """ Matches the fk bones in a leg rig to the ik bones. + obj: armature object + fk: list of fk bone names + ik: list of ik bone names + """ + thigh = obj.pose.bones[fk[0]] + shin = obj.pose.bones[fk[1]] + foot = obj.pose.bones[fk[2]] + mfoot = obj.pose.bones[fk[3]] + thighi = obj.pose.bones[ik[0]] + shini = obj.pose.bones[ik[1]] + footi = obj.pose.bones[ik[2]] + mfooti = obj.pose.bones[ik[3]] + + # Stretch + if footi['auto_stretch'] == 0.0: + thigh['stretch_length'] = footi['stretch_length'] + else: + diff = (thighi.vector.length + shini.vector.length) / (thigh.vector.length + shin.vector.length) + thigh['stretch_length'] *= diff + + # Thigh position + match_pose_rotation(thigh, thighi) + match_pose_scale(thigh, thighi) + + # Shin position + match_pose_rotation(shin, shini) + match_pose_scale(shin, shini) + + # Foot position + mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local + footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat + set_pose_rotation(foot, footmat) + set_pose_scale(foot, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + +def ik2fk_leg(obj, fk, ik): + """ Matches the ik bones in a leg rig to the fk bones. + obj: armature object + fk: list of fk bone names + ik: list of ik bone names + """ + thigh = obj.pose.bones[fk[0]] + shin = obj.pose.bones[fk[1]] + mfoot = obj.pose.bones[fk[2]] + thighi = obj.pose.bones[ik[0]] + shini = obj.pose.bones[ik[1]] + footi = obj.pose.bones[ik[2]] + footroll = obj.pose.bones[ik[3]] + pole = obj.pose.bones[ik[4]] + mfooti = obj.pose.bones[ik[5]] + + # Stretch + footi['stretch_length'] = thigh['stretch_length'] + + # Clear footroll + set_pose_rotation(footroll, Matrix()) + + # Foot position + mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local + footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) * mat + set_pose_translation(footi, footmat) + set_pose_rotation(footi, footmat) + set_pose_scale(footi, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + # Pole target position + match_pole_target(thighi, shini, pole, thigh, (thighi.length + shini.length)) + + +############################## +## IK/FK snapping operators ## +############################## + +class Rigify_Arm_FK2IK(bpy.types.Operator): + """ Snaps an FK arm to an IK arm. + """ + bl_idname = "pose.rigify_arm_fk2ik_" + rig_id + bl_label = "Rigify Snap FK arm to IK" + bl_options = {'UNDO'} + + uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name") + farm_fk = bpy.props.StringProperty(name="Forerm FK Name") + hand_fk = bpy.props.StringProperty(name="Hand FK Name") + + uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name") + farm_ik = bpy.props.StringProperty(name="Forearm IK Name") + hand_ik = bpy.props.StringProperty(name="Hand IK Name") + + @classmethod + def poll(cls, context): + return (context.active_object is not None and context.mode == 'POSE') + + def execute(self, context): + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + fk2ik_arm(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik]) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + return {'FINISHED'} + + +class Rigify_Arm_IK2FK(bpy.types.Operator): + """ Snaps an IK arm to an FK arm. + """ + bl_idname = "pose.rigify_arm_ik2fk_" + rig_id + bl_label = "Rigify Snap IK arm to FK" + bl_options = {'UNDO'} + + uarm_fk = bpy.props.StringProperty(name="Upper Arm FK Name") + farm_fk = bpy.props.StringProperty(name="Forerm FK Name") + hand_fk = bpy.props.StringProperty(name="Hand FK Name") + + uarm_ik = bpy.props.StringProperty(name="Upper Arm IK Name") + farm_ik = bpy.props.StringProperty(name="Forearm IK Name") + hand_ik = bpy.props.StringProperty(name="Hand IK Name") + pole = bpy.props.StringProperty(name="Pole IK Name") + + @classmethod + def poll(cls, context): + return (context.active_object is not None and context.mode == 'POSE') + + def execute(self, context): + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + ik2fk_arm(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik, self.pole]) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + return {'FINISHED'} + + +class Rigify_Leg_FK2IK(bpy.types.Operator): + """ Snaps an FK leg to an IK leg. + """ + bl_idname = "pose.rigify_leg_fk2ik_" + rig_id + bl_label = "Rigify Snap FK leg to IK" + bl_options = {'UNDO'} + + thigh_fk = bpy.props.StringProperty(name="Thigh FK Name") + shin_fk = bpy.props.StringProperty(name="Shin FK Name") + foot_fk = bpy.props.StringProperty(name="Foot FK Name") + mfoot_fk = bpy.props.StringProperty(name="MFoot FK Name") + + thigh_ik = bpy.props.StringProperty(name="Thigh IK Name") + shin_ik = bpy.props.StringProperty(name="Shin IK Name") + foot_ik = bpy.props.StringProperty(name="Foot IK Name") + mfoot_ik = bpy.props.StringProperty(name="MFoot IK Name") + + @classmethod + def poll(cls, context): + return (context.active_object is not None and context.mode == 'POSE') + + def execute(self, context): + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + fk2ik_leg(context.active_object, fk=[self.thigh_fk, self.shin_fk, self.foot_fk, self.mfoot_fk], ik=[self.thigh_ik, self.shin_ik, self.foot_ik, self.mfoot_ik]) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + return {'FINISHED'} + + +class Rigify_Leg_IK2FK(bpy.types.Operator): + """ Snaps an IK leg to an FK leg. + """ + bl_idname = "pose.rigify_leg_ik2fk_" + rig_id + bl_label = "Rigify Snap IK leg to FK" + bl_options = {'UNDO'} + + thigh_fk = bpy.props.StringProperty(name="Thigh FK Name") + shin_fk = bpy.props.StringProperty(name="Shin FK Name") + mfoot_fk = bpy.props.StringProperty(name="MFoot FK Name") + + thigh_ik = bpy.props.StringProperty(name="Thigh IK Name") + shin_ik = bpy.props.StringProperty(name="Shin IK Name") + foot_ik = bpy.props.StringProperty(name="Foot IK Name") + footroll = bpy.props.StringProperty(name="Foot Roll Name") + pole = bpy.props.StringProperty(name="Pole IK Name") + mfoot_ik = bpy.props.StringProperty(name="MFoot IK Name") + + @classmethod + def poll(cls, context): + return (context.active_object is not None and context.mode == 'POSE') + + def execute(self, context): + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + ik2fk_leg(context.active_object, fk=[self.thigh_fk, self.shin_fk, self.mfoot_fk], ik=[self.thigh_ik, self.shin_ik, self.foot_ik, self.footroll, self.pole, self.mfoot_ik]) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + return {'FINISHED'} + + +################### +## Rig UI Panels ## +################### + +class RigUI(bpy.types.Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_label = "Rig Main Properties" + bl_idname = rig_id + "_PT_rig_ui" + + @classmethod + def poll(self, context): + if context.mode != 'POSE': + return False + try: + return (context.active_object.data.get("rig_id") == rig_id) + except (AttributeError, KeyError, TypeError): + return False + + def draw(self, context): + layout = self.layout + pose_bones = context.active_object.pose.bones + try: + selected_bones = [bone.name for bone in context.selected_pose_bones] + selected_bones += [context.active_pose_bone.name] + except (AttributeError, TypeError): + return + + def is_selected(names): + # Returns whether any of the named bones are selected. + if type(names) == list: + for name in names: + if name in selected_bones: + return True + elif names in selected_bones: + return True + return False + + +''' + + +def layers_ui(layers, layout): + """ Turn a list of booleans + a list of names into a layer UI. + """ + + code = ''' +class RigLayers(bpy.types.Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_label = "Rig Layers" + bl_idname = rig_id + "_PT_rig_layers" + + @classmethod + def poll(self, context): + try: + return (context.active_object.data.get("rig_id") == rig_id) + except (AttributeError, KeyError, TypeError): + return False + + def draw(self, context): + layout = self.layout + col = layout.column() +''' + rows = {} + for i in range(28): + if layers[i]: + if layout[i][1] not in rows: + rows[layout[i][1]] = [] + rows[layout[i][1]] += [(layout[i][0], i)] + + keys = list(rows.keys()) + keys.sort() + + for key in keys: + code += "\n row = col.row()\n" + i = 0 + for l in rows[key]: + if i > 3: + code += "\n row = col.row()\n" + i = 0 + code += " row.prop(context.active_object.data, 'layers', index=%s, toggle=True, text='%s')\n" % (str(l[1]), l[0]) + i += 1 + + # Root layer + code += "\n row = col.row()" + code += "\n row.separator()" + code += "\n row = col.row()" + code += "\n row.separator()\n" + code += "\n row = col.row()\n" + code += " row.prop(context.active_object.data, 'layers', index=28, toggle=True, text='Root')\n" + + return code + + +UI_REGISTER = ''' + +def register(): + bpy.utils.register_class(Rigify_Arm_FK2IK) + bpy.utils.register_class(Rigify_Arm_IK2FK) + bpy.utils.register_class(Rigify_Leg_FK2IK) + bpy.utils.register_class(Rigify_Leg_IK2FK) + bpy.utils.register_class(RigUI) + bpy.utils.register_class(RigLayers) + +def unregister(): + bpy.utils.unregister_class(Rigify_Arm_FK2IK) + bpy.utils.unregister_class(Rigify_Arm_IK2FK) + bpy.utils.unregister_class(Rigify_Leg_FK2IK) + bpy.utils.unregister_class(Rigify_Leg_IK2FK) + bpy.utils.unregister_class(RigUI) + bpy.utils.unregister_class(RigLayers) + +register() +''' diff --git a/rigify/rigs/pitchipoy/__init__.py b/rigify/legacy/rigs/__init__.py similarity index 100% rename from rigify/rigs/pitchipoy/__init__.py rename to rigify/legacy/rigs/__init__.py diff --git a/rigify/rigs/pitchipoy/limbs/__init__.py b/rigify/legacy/rigs/basic/__init__.py similarity index 100% rename from rigify/rigs/pitchipoy/limbs/__init__.py rename to rigify/legacy/rigs/basic/__init__.py diff --git a/rigify/rigs/basic/copy.py b/rigify/legacy/rigs/basic/copy.py similarity index 100% rename from rigify/rigs/basic/copy.py rename to rigify/legacy/rigs/basic/copy.py diff --git a/rigify/legacy/rigs/basic/copy_chain.py b/rigify/legacy/rigs/basic/copy_chain.py new file mode 100644 index 0000000000000000000000000000000000000000..4e4262846924799500f8c936e50f020ae9b18e54 --- /dev/null +++ b/rigify/legacy/rigs/basic/copy_chain.py @@ -0,0 +1,206 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +import bpy + +from ...utils import MetarigError +from ...utils import copy_bone +from ...utils import connected_children_names +from ...utils import strip_org, make_deformer_name +from ...utils import create_bone_widget + + +class Rig: + """ A "copy_chain" rig. All it does is duplicate the original bone chain + and constrain it. + This is a control and deformation rig. + + """ + def __init__(self, obj, bone_name, params): + """ Gather and validate data about the rig. + """ + self.obj = obj + self.org_bones = [bone_name] + connected_children_names(obj, bone_name) + self.params = params + self.make_controls = params.make_controls + self.make_deforms = params.make_deforms + + if len(self.org_bones) <= 1: + raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 2 or more bones" % (strip_org(bone_name))) + + 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') + + # Create the deformation and control bone chains. + # Just copies of the original chain. + def_chain = [] + ctrl_chain = [] + for i in range(len(self.org_bones)): + name = self.org_bones[i] + + # Control bone + if self.make_controls: + # Copy + ctrl_bone = copy_bone(self.obj, name) + eb = self.obj.data.edit_bones + ctrl_bone_e = eb[ctrl_bone] + # Name + ctrl_bone_e.name = strip_org(name) + # Parenting + if i == 0: + # First bone + ctrl_bone_e.parent = eb[self.org_bones[0]].parent + else: + # The rest + ctrl_bone_e.parent = eb[ctrl_chain[-1]] + # Add to list + ctrl_chain += [ctrl_bone_e.name] + else: + ctrl_chain += [None] + + # Deformation bone + if self.make_deforms: + # Copy + def_bone = copy_bone(self.obj, name) + eb = self.obj.data.edit_bones + def_bone_e = eb[def_bone] + # Name + def_bone_e.name = make_deformer_name(strip_org(name)) + # Parenting + if i == 0: + # First bone + def_bone_e.parent = eb[self.org_bones[0]].parent + else: + # The rest + def_bone_e.parent = eb[def_chain[-1]] + # Add to list + def_chain += [def_bone_e.name] + else: + def_chain += [None] + + bpy.ops.object.mode_set(mode='OBJECT') + pb = self.obj.pose.bones + + # Constraints for org and def + for org, ctrl, defrm in zip(self.org_bones, ctrl_chain, def_chain): + if self.make_controls: + con = pb[org].constraints.new('COPY_TRANSFORMS') + con.name = "copy_transforms" + con.target = self.obj + con.subtarget = ctrl + + if self.make_deforms: + con = pb[defrm].constraints.new('COPY_TRANSFORMS') + con.name = "copy_transforms" + con.target = self.obj + con.subtarget = org + + # Create control widgets + if self.make_controls: + for bone in ctrl_chain: + create_bone_widget(self.obj, bone) + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + params.make_controls = bpy.props.BoolProperty(name="Controls", default=True, description="Create control bones for the copy") + params.make_deforms = bpy.props.BoolProperty(name="Deform", default=True, description="Create deform bones for the copy") + + +def parameters_ui(layout, params): + """ Create the ui for the rig parameters. + """ + r = layout.row() + r.prop(params, "make_controls") + r = layout.row() + r.prop(params, "make_deforms") + + +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.01') + 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.01'] = bone.name + bone = arm.edit_bones.new('bone.02') + bone.head[:] = 0.0000, 0.0000, 0.3333 + bone.tail[:] = 0.0000, 0.0000, 0.6667 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['bone.01']] + bones['bone.02'] = bone.name + bone = arm.edit_bones.new('bone.03') + bone.head[:] = 0.0000, 0.0000, 0.6667 + bone.tail[:] = 0.0000, 0.0000, 1.0000 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['bone.02']] + bones['bone.03'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['bone.01']] + pbone.rigify_type = 'basic.copy_chain' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone = obj.pose.bones[bones['bone.02']] + 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.03']] + 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/biped/__init__.py b/rigify/legacy/rigs/biped/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/biped/arm/__init__.py b/rigify/legacy/rigs/biped/arm/__init__.py similarity index 100% rename from rigify/rigs/biped/arm/__init__.py rename to rigify/legacy/rigs/biped/arm/__init__.py diff --git a/rigify/rigs/biped/arm/deform.py b/rigify/legacy/rigs/biped/arm/deform.py similarity index 100% rename from rigify/rigs/biped/arm/deform.py rename to rigify/legacy/rigs/biped/arm/deform.py diff --git a/rigify/rigs/biped/arm/fk.py b/rigify/legacy/rigs/biped/arm/fk.py similarity index 100% rename from rigify/rigs/biped/arm/fk.py rename to rigify/legacy/rigs/biped/arm/fk.py diff --git a/rigify/rigs/biped/arm/ik.py b/rigify/legacy/rigs/biped/arm/ik.py similarity index 100% rename from rigify/rigs/biped/arm/ik.py rename to rigify/legacy/rigs/biped/arm/ik.py diff --git a/rigify/rigs/biped/leg/__init__.py b/rigify/legacy/rigs/biped/leg/__init__.py similarity index 100% rename from rigify/rigs/biped/leg/__init__.py rename to rigify/legacy/rigs/biped/leg/__init__.py diff --git a/rigify/rigs/biped/leg/deform.py b/rigify/legacy/rigs/biped/leg/deform.py similarity index 100% rename from rigify/rigs/biped/leg/deform.py rename to rigify/legacy/rigs/biped/leg/deform.py diff --git a/rigify/rigs/biped/leg/fk.py b/rigify/legacy/rigs/biped/leg/fk.py similarity index 100% rename from rigify/rigs/biped/leg/fk.py rename to rigify/legacy/rigs/biped/leg/fk.py diff --git a/rigify/rigs/biped/leg/ik.py b/rigify/legacy/rigs/biped/leg/ik.py similarity index 100% rename from rigify/rigs/biped/leg/ik.py rename to rigify/legacy/rigs/biped/leg/ik.py diff --git a/rigify/rigs/biped/limb_common.py b/rigify/legacy/rigs/biped/limb_common.py similarity index 100% rename from rigify/rigs/biped/limb_common.py rename to rigify/legacy/rigs/biped/limb_common.py diff --git a/rigify/rigs/finger.py b/rigify/legacy/rigs/finger.py similarity index 100% rename from rigify/rigs/finger.py rename to rigify/legacy/rigs/finger.py diff --git a/rigify/legacy/rigs/misc/__init__.py b/rigify/legacy/rigs/misc/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/legacy/rigs/misc/delta.py b/rigify/legacy/rigs/misc/delta.py new file mode 100644 index 0000000000000000000000000000000000000000..84f3612b2d2fcb34db3ae798263c57b78b1b4fe5 --- /dev/null +++ b/rigify/legacy/rigs/misc/delta.py @@ -0,0 +1,165 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +if False: + # This rig type is disabled due to its obscurity. + # However, some of the code may be useful in the future, so + # I'm leaving it here. + from math import acos + + import bpy + + from ...utils import MetarigError + from ...utils import copy_bone + from ...utils import org_name, make_mechanism_name + + + class Rig: + """ A delta rig. + Creates a setup that will place its child at its position in pose mode, + but will not modifying its child's position in edit mode. + This is a mechanism-only rig (no control or deformation bones). + + """ + def __init__(self, obj, bone, params): + """ Gather and validate data about the rig. + Store any data or references to data that will be needed later on. + In particular, store references to bones that will be needed. + Do NOT change any data in the scene. This is a gathering phase only. + + """ + bb = obj.data.bones + + if bb[bone].children is None: + raise MetarigError("RIGIFY ERROR: bone '%s': rig type requires one child" % org_name(bone.name)) + if bb[bone].use_connect is True: + raise MetarigError("RIGIFY ERROR: bone '%s': rig type cannot be connected to parent" % org_name(bone.name)) + + self.obj = obj + self.org_bones = {"delta": bone, "child": bb[bone].children[0].name} + self.org_names = [org_name(bone), org_name(bb[bone].children[0].name)] + + 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') + eb = self.obj.data.edit_bones + + org_delta = self.org_bones["delta"] + org_delta_e = eb[self.org_bones["delta"]] + # org_child = self.org_bones["child"] # UNUSED + org_child_e = eb[self.org_bones["child"]] + + # Calculate the matrix for achieving the delta + child_mat = org_delta_e.matrix.invert() * org_child_e.matrix + mat = org_delta_e.matrix * child_mat.invert() + + # Create the delta bones. + delta_e = eb[copy_bone(self.obj, self.org_bones["delta"])] + delta_e.name = make_mechanism_name(self.org_names[0]) + delta = delta_e.name + + # Set the delta to the matrix's transforms + set_mat(self.obj, delta, mat) + + bpy.ops.object.mode_set(mode='OBJECT') + + # Constrain org_delta to delta + con = self.obj.pose.bones[org_delta].constraints.new('COPY_TRANSFORMS') + con.name = "delta" + con.target = self.obj + con.subtarget = delta + + 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('delta') + bone.head[:] = 0.0000, -0.1198, 0.1253 + bone.tail[:] = -0.0000, -0.2483, 0.2785 + bone.roll = -0.0000 + bone.use_connect = False + bones['delta'] = bone.name + 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 + bone.parent = arm.edit_bones[bones['delta']] + bones['Bone'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['delta']] + pbone.rigify_type = 'misc.delta' + 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']] + 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 set_mat(obj, bone_name, matrix): + """ Sets the bone to have the given transform matrix. + """ + a = obj.data.edit_bones[bone_name] + + a.head = (0, 0, 0) + a.tail = (0, 1, 0) + + a.transform(matrix) + + d = acos(a.matrix.to_quaternion().dot(matrix.to_quaternion())) * 2.0 + + roll_1 = a.roll + d + roll_2 = a.roll - d + + a.roll = roll_1 + d1 = a.matrix.to_quaternion().dot(matrix.to_quaternion()) + a.roll = roll_2 + d2 = a.matrix.to_quaternion().dot(matrix.to_quaternion()) + + if d1 > d2: + a.roll = roll_1 + else: + a.roll = roll_2 diff --git a/rigify/rigs/neck_short.py b/rigify/legacy/rigs/neck_short.py similarity index 100% rename from rigify/rigs/neck_short.py rename to rigify/legacy/rigs/neck_short.py diff --git a/rigify/rigs/palm.py b/rigify/legacy/rigs/palm.py similarity index 100% rename from rigify/rigs/palm.py rename to rigify/legacy/rigs/palm.py diff --git a/rigify/legacy/rigs/pitchipoy/__init__.py b/rigify/legacy/rigs/pitchipoy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/legacy/rigs/pitchipoy/limbs/__init__.py b/rigify/legacy/rigs/pitchipoy/limbs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/pitchipoy/limbs/arm.py b/rigify/legacy/rigs/pitchipoy/limbs/arm.py similarity index 97% rename from rigify/rigs/pitchipoy/limbs/arm.py rename to rigify/legacy/rigs/pitchipoy/limbs/arm.py index 17bf5535304d5344546943e700eebd30874a2e31..43327ec89e053d5d118c4709f746286e4300dd9a 100644 --- a/rigify/rigs/pitchipoy/limbs/arm.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/arm.py @@ -27,26 +27,26 @@ 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) + # clear parent (so that rigify will parent to root) eb[ ctrl ].parent = None eb[ ctrl ].use_connect = False - # Parent + # 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'], @@ -80,7 +80,7 @@ def create_arm( cls, bones ): # 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 @@ -93,7 +93,7 @@ def create_arm( cls, bones ): 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" @@ -102,7 +102,7 @@ def create_arm( cls, bones ): 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 diff --git a/rigify/rigs/pitchipoy/limbs/leg.py b/rigify/legacy/rigs/pitchipoy/limbs/leg.py similarity index 94% rename from rigify/rigs/pitchipoy/limbs/leg.py rename to rigify/legacy/rigs/pitchipoy/limbs/leg.py index 14fd6f13157f4a3a6f78ac2679840d73924620b3..9176bd92ffd34203b6f046053c1bc6444b6223c5 100644 --- a/rigify/rigs/pitchipoy/limbs/leg.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/leg.py @@ -31,7 +31,7 @@ def create_leg( cls, bones ): ) bones['ik']['ctrl']['terminal'] = [] - + bpy.ops.object.mode_set(mode='EDIT') eb = cls.obj.data.edit_bones @@ -49,7 +49,7 @@ def create_leg( cls, bones ): 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) + # clear parent (so that rigify will parent to root) eb[ ctrl ].parent = None eb[ ctrl ].use_connect = False @@ -64,7 +64,7 @@ def create_leg( cls, bones ): orient_bone( cls, eb[ ctrl ], 'y', reverse = True ) eb[ ctrl ].length = l - # Parent + # Parent eb[ heel ].use_connect = False eb[ heel ].parent = eb[ ctrl ] @@ -91,38 +91,38 @@ def create_leg( cls, bones ): # 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 ) + 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, + + 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 ) + rock1_mch = copy_bone( cls.obj, tmp_heel, rock1_mch ) eb[ rock1_mch ].use_connect = False - eb[ rock1_mch ].parent = None - + 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 + 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 ] @@ -135,7 +135,7 @@ def create_leg( cls, bones ): 'subtarget' : heel, 'owner_space' : 'LOCAL', 'target_space' : 'LOCAL' - }) + }) make_constraint( cls, roll1_mch, { 'constraint' : 'LIMIT_ROTATION', 'use_limit_x' : True, @@ -150,15 +150,15 @@ def create_leg( cls, bones ): '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 + 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: @@ -176,7 +176,7 @@ def create_leg( cls, bones ): min_y = 0 max_y = math.radians(360) - + make_constraint( cls, b, { 'constraint' : 'COPY_ROTATION', 'subtarget' : heel, @@ -184,14 +184,14 @@ def create_leg( cls, bones ): '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], { @@ -201,7 +201,7 @@ def create_leg( cls, bones ): # 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'], @@ -235,7 +235,7 @@ def create_leg( cls, bones ): # 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 @@ -248,7 +248,7 @@ def create_leg( cls, bones ): 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" @@ -257,7 +257,7 @@ def create_leg( cls, bones ): 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 @@ -284,7 +284,7 @@ def create_leg( cls, bones ): 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', @@ -293,8 +293,8 @@ def create_leg( cls, bones ): make_constraint( cls, bones['def'][-2], { 'constraint' : 'STRETCH_TO', 'subtarget' : toes - }) - + }) + make_constraint( cls, bones['def'][-1], { 'constraint' : 'COPY_TRANSFORMS', 'subtarget' : toes @@ -303,12 +303,12 @@ def create_leg( cls, bones ): # 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" @@ -317,17 +317,17 @@ def create_leg( cls, bones ): 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/rigs/pitchipoy/limbs/limb_utils.py b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py similarity index 93% rename from rigify/rigs/pitchipoy/limbs/limb_utils.py rename to rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py index ce6a0761fe278a9e329750398e00602d6ccd2750..73e4f47206b36293cf102a3a7c165e8affe7dd3c 100644 --- a/rigify/rigs/pitchipoy/limbs/limb_utils.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/limb_utils.py @@ -7,13 +7,13 @@ 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 + eb.tail[:] = eb.head + tail_vec else: tail_vec = v * cls.obj.matrix_world eb.tail[:] = eb.head + tail_vec @@ -29,22 +29,22 @@ def make_constraint( cls, bone, constraint ): constraint['target'] = cls.obj - # filter contraint props to those that actually exist in the currnet + # 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" % ( + "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 (".") + # 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+)$' + pattern = r'^(\S+)(\.\S+)$' name = strip_org( name ) @@ -60,7 +60,7 @@ def get_bone_name( name, btype, suffix = '' ): if suffix: results = re.match( pattern, name ) bname, addition = ('','') - + if results: bname, addition = results.groups() name = bname + "_" + suffix + addition diff --git a/rigify/rigs/pitchipoy/limbs/paw.py b/rigify/legacy/rigs/pitchipoy/limbs/paw.py similarity index 98% rename from rigify/rigs/pitchipoy/limbs/paw.py rename to rigify/legacy/rigs/pitchipoy/limbs/paw.py index 03ccd25f92564b06873e997d9517eddbe10d7d84..89de5e90d3d99a4b51180d0b3e7a36c2656b4c21 100644 --- a/rigify/rigs/pitchipoy/limbs/paw.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/paw.py @@ -32,7 +32,7 @@ def create_paw( cls, bones ): bones['ik']['ctrl']['terminal'] = [] - + bpy.ops.object.mode_set(mode='EDIT') eb = cls.obj.data.edit_bones @@ -57,7 +57,7 @@ def create_paw( cls, bones ): 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 @@ -68,7 +68,7 @@ def create_paw( cls, bones ): # 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'], @@ -104,7 +104,7 @@ def create_paw( cls, bones ): # 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 @@ -117,7 +117,7 @@ def create_paw( cls, bones ): 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" @@ -126,7 +126,7 @@ def create_paw( cls, bones ): 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 @@ -151,7 +151,7 @@ def create_paw( cls, bones ): 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 ) @@ -160,7 +160,7 @@ def create_paw( cls, bones ): 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', @@ -184,12 +184,12 @@ def create_paw( cls, bones ): # 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" @@ -198,12 +198,12 @@ def create_paw( cls, bones ): 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) diff --git a/rigify/rigs/pitchipoy/limbs/super_limb.py b/rigify/legacy/rigs/pitchipoy/limbs/super_limb.py similarity index 93% rename from rigify/rigs/pitchipoy/limbs/super_limb.py rename to rigify/legacy/rigs/pitchipoy/limbs/super_limb.py index b1d58ea7b5c76cab07ab13784db3af21fe8ce545..91efdb48f04b22a183c81b67d38238ec227c65d0 100644 --- a/rigify/rigs/pitchipoy/limbs/super_limb.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/super_limb.py @@ -14,11 +14,13 @@ 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 torso rig and key rig properties """ - self.obj = obj - self.params = params + """ Initialize super_limb rig and key rig properties """ + self.obj = obj + self.params = params if params.limb_type != 'paw': self.org_bones = list( @@ -29,10 +31,10 @@ class Rig: [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.segments = params.segments + self.bbones = params.bbones self.limb_type = params.limb_type - self.rot_axis = params.rotation_axis + self.rot_axis = params.rotation_axis # Assign values to tweak/FK layers props if opted by user if params.tweak_extra_layers: @@ -45,9 +47,9 @@ class Rig: else: self.fk_layers = None - def create_parent( self ): + def create_parent(self): org_bones = self.org_bones - + bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones @@ -58,9 +60,9 @@ class Rig: 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', @@ -71,7 +73,7 @@ class Rig: 'constraint' : 'COPY_SCALE', 'subtarget' : 'root' }) - + # Limb Follow Driver pb = self.obj.pose.bones @@ -79,7 +81,7 @@ class Rig: 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 @@ -100,11 +102,11 @@ class Rig: def create_tweak( self ): org_bones = self.org_bones - + bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones - tweaks = {} + tweaks = {} tweaks['ctrl'] = [] tweaks['mch' ] = [] @@ -116,15 +118,15 @@ class Rig: # 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 + # 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) @@ -137,23 +139,23 @@ class Rig: 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' ) + 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, + 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 + 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 ] @@ -256,19 +258,19 @@ class Rig: 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 - + 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: @@ -276,7 +278,7 @@ class Rig: 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 @@ -338,7 +340,7 @@ class Rig: 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 @@ -365,13 +367,13 @@ class Rig: 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 @@ -387,7 +389,7 @@ class Rig: # Create MCH Stretch mch_str = copy_bone( - self.obj, + self.obj, org_bones[0], get_bone_name( org_bones[0], 'mch', 'ik_stretch' ) ) @@ -396,13 +398,13 @@ class Rig: 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, @@ -421,13 +423,13 @@ class Rig: # 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, + + 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() @@ -438,19 +440,19 @@ class Rig: bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones - ctrls = [] + 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( + 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] ] @@ -464,7 +466,7 @@ class Rig: 'constraint' : 'COPY_SCALE', 'subtarget' : 'root' }) - + # Locks and widgets pb = self.obj.pose.bones pb[ ctrls[2] ].lock_location = True, True, True @@ -479,7 +481,7 @@ class Rig: 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') @@ -517,11 +519,11 @@ class Rig: '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" @@ -547,48 +549,48 @@ class Rig: 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['tweak'] = self.create_tweak() bones['def'] = self.create_def( bones['tweak']['ctrl'] ) bones['ik'] = self.create_ik( bones['parent'] ) bones['fk'] = self.create_fk( bones['parent'] ) - self.org_parenting_and_switch( - self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] + self.org_parenting_and_switch( + self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] ) bones = self.create_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', ''), + ('arm', 'Arm', ''), + ('leg', 'Leg', ''), ('paw', 'Paw', '') ] params.limb_type = bpy.props.EnumProperty( - items = items, - name = "Limb Type", + items = items, + name = "Limb Type", default = 'arm' ) items = [ - ('x', 'X', ''), - ('y', 'Y', ''), + ('x', 'X', ''), + ('y', 'Y', ''), ('z', 'Z', '') ] params.rotation_axis = bpy.props.EnumProperty( - items = items, - name = "Rotation Axis", + items = items, + name = "Rotation Axis", default = 'x' ) @@ -598,7 +600,7 @@ def add_parameters( params ): min = 1, description = 'Number of segments' ) - + params.bbones = bpy.props.IntProperty( name = 'bbone segments', default = 10, @@ -607,9 +609,9 @@ def add_parameters( params ): ) # Setting up extra layers for the FK and tweak - params.tweak_extra_layers = bpy.props.BoolProperty( - name = "tweak_extra_layers", - default = True, + params.tweak_extra_layers = bpy.props.BoolProperty( + name = "tweak_extra_layers", + default = True, description = "" ) @@ -618,11 +620,11 @@ def add_parameters( params ): 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, + params.fk_extra_layers = bpy.props.BoolProperty( + name = "fk_extra_layers", + default = True, description = "" ) @@ -638,7 +640,7 @@ def parameters_ui(layout, params): r = layout.row() r.prop(params, "limb_type") - + r = layout.row() r.prop(params, "rotation_axis") @@ -652,7 +654,7 @@ def parameters_ui(layout, params): 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) @@ -716,7 +718,7 @@ def create_sample(obj): except AttributeError: pass try: - pbone.rigify_parameters.ik_layers = [ + 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, diff --git a/rigify/rigs/pitchipoy/limbs/ui.py b/rigify/legacy/rigs/pitchipoy/limbs/ui.py similarity index 98% rename from rigify/rigs/pitchipoy/limbs/ui.py rename to rigify/legacy/rigs/pitchipoy/limbs/ui.py index a7ed95a702374d321acbffed23461b2835ed528b..37921dc0ed2f2faeda114d335dbf067f9d3f63f8 100644 --- a/rigify/rigs/pitchipoy/limbs/ui.py +++ b/rigify/legacy/rigs/pitchipoy/limbs/ui.py @@ -29,15 +29,15 @@ if is_selected( controls ): 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] @@ -95,8 +95,8 @@ def create_script( bones, limb_type=None): # 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 has IK stretch ik_ctrl = [ bones['ik']['ctrl']['terminal'][-1] ] ik_ctrl += [ bones['ik']['mch_ik'] ] ik_ctrl += [ bones['ik']['mch_target'] ] diff --git a/rigify/rigs/pitchipoy/simple_tentacle.py b/rigify/legacy/rigs/pitchipoy/simple_tentacle.py similarity index 94% rename from rigify/rigs/pitchipoy/simple_tentacle.py rename to rigify/legacy/rigs/pitchipoy/simple_tentacle.py index 9351a6595d190d26a9105ad5dd082f77c0fb8af8..4edb15e6919b8e8f694acb22015bae22687ea2b0 100644 --- a/rigify/rigs/pitchipoy/simple_tentacle.py +++ b/rigify/legacy/rigs/pitchipoy/simple_tentacle.py @@ -7,27 +7,27 @@ 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 @@ -36,8 +36,8 @@ class Rig: name = org_bones[i] ctrl_bone = copy_bone( - self.obj, - name, + self.obj, + name, strip_org(name) ) @@ -48,12 +48,12 @@ class Rig: 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 @@ -67,19 +67,19 @@ class Rig: name = org_bones[i] tweak_bone = copy_bone( - self.obj, - name, + 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 @@ -102,12 +102,12 @@ class Rig: # Set up tweak bone layers if self.tweak_layers: tweak_pb.bone.layers = self.tweak_layers - - return tweak_chain + + return tweak_chain def make_deform( self ): - + bpy.ops.object.mode_set(mode ='EDIT') org_bones = self.org_bones @@ -116,18 +116,18 @@ class Rig: name = org_bones[i] def_bone = copy_bone( - self.obj, - name, + 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 @@ -136,7 +136,7 @@ class Rig: 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']: @@ -145,7 +145,7 @@ class Rig: parent = all_bones['control'][ -1 ] else: parent = all_bones['control'][ tweaks.index( tweak ) ] - + eb[ tweak ].parent = eb[ parent ] # Parent deform bones @@ -157,15 +157,15 @@ class Rig: # 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 ] - - + 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' ] @@ -175,15 +175,15 @@ class Rig: 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') @@ -198,7 +198,7 @@ class Rig: con.target_space = 'LOCAL' con.owner_space = 'LOCAL' - + def generate(self): bpy.ops.object.mode_set(mode ='EDIT') @@ -208,7 +208,7 @@ class Rig: 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() @@ -219,7 +219,7 @@ class Rig: 'tweak' : tweak_chain, 'deform' : def_chain } - + self.make_constraints( all_bones ) self.parent_bones( all_bones ) @@ -233,10 +233,10 @@ def add_parameters(params): 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", + params.tweak_extra_layers = bpy.props.BoolProperty( + name = "tweak_extra_layers", default = True, description = "" ) @@ -261,7 +261,7 @@ def parameters_ui(layout, params): 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) @@ -271,19 +271,19 @@ def parameters_ui(layout, params): row = col.row(align=True) for i in range( 16, 24 ): # Layers 16-23 - row.prop(params, "tweak_layers", index=i, toggle=True, text="") - + 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.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') @@ -297,7 +297,7 @@ def create_sample(obj): 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 @@ -305,7 +305,7 @@ def create_sample(obj): 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 @@ -313,7 +313,7 @@ def create_sample(obj): 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' diff --git a/rigify/rigs/pitchipoy/super_copy.py b/rigify/legacy/rigs/pitchipoy/super_copy.py similarity index 89% rename from rigify/rigs/pitchipoy/super_copy.py rename to rigify/legacy/rigs/pitchipoy/super_copy.py index 27e887750ce5c369e36f1cbfa9f62a0408fba3eb..d05d68c465ee47fc33bbd5037ec455419e8b1f86 100644 --- a/rigify/rigs/pitchipoy/super_copy.py +++ b/rigify/legacy/rigs/pitchipoy/super_copy.py @@ -91,22 +91,22 @@ 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_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_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" + params.make_deform = bpy.props.BoolProperty( + name = "Deform", + default = True, + description = "Create a deform bone for the copy" ) diff --git a/rigify/rigs/pitchipoy/super_face.py b/rigify/legacy/rigs/pitchipoy/super_face.py old mode 100755 new mode 100644 similarity index 97% rename from rigify/rigs/pitchipoy/super_face.py rename to rigify/legacy/rigs/pitchipoy/super_face.py index 341596a1a059ad935eca201c188062fd13e3a2a4..9928864fdaaa5072d8a66a003b29ae69b4dea27d --- a/rigify/rigs/pitchipoy/super_face.py +++ b/rigify/legacy/rigs/pitchipoy/super_face.py @@ -18,17 +18,17 @@ if is_selected(all_controls): 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", + 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", + "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" ] @@ -40,7 +40,7 @@ class Rig: 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 @@ -58,22 +58,22 @@ class Rig: def symmetrical_split( self, bones ): # RE pattern match right or left parts - # match the letter "L" (or "R"), followed by an optional dot (".") + # 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*$' + 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 ) ] ) + 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: @@ -97,12 +97,12 @@ class Rig: brow_left.reverse() brow_right.reverse() - for browL, browR, foreheadL, foreheadR in zip( + 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 } @@ -112,53 +112,53 @@ class Rig: ## 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, + 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 ) @@ -171,29 +171,29 @@ class Rig: 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 ) @@ -203,25 +203,25 @@ class Rig: # 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, + return { + 'eyes' : [ + eyeL_ctrl_name, + eyeR_ctrl_name, eyes_ctrl_name, ] + eye_master_names, 'ears' : [ earL_ctrl_name, earR_ctrl_name ], @@ -230,7 +230,7 @@ class Rig: 'tongue' : [ tongue_ctrl_name ], 'nose' : [ master_nose ] } - + def create_tweak( self, bones, uniques, tails ): org_bones = self.org_bones @@ -240,7 +240,7 @@ class Rig: eb = self.obj.data.edit_bones tweaks = [] - + for bone in bones + list( uniques.keys() ): tweak_name = strip_org( bone ) @@ -273,21 +273,21 @@ class Rig: 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", + "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: @@ -297,7 +297,7 @@ class Rig: if self.secondary_layers: pb[bone].bone.layers = self.secondary_layers create_face_widget( self.obj, bone ) - + return { 'all' : tweaks } @@ -322,20 +322,20 @@ class Rig: 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_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.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 ] @@ -343,14 +343,14 @@ class Rig: 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 ] @@ -372,24 +372,24 @@ class Rig: 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'] = [] @@ -403,11 +403,11 @@ class Rig: eb[ mch_name ].parent = None eb[ mch_name ].tail[:] = eb[ bone ].head - - mch_bones['lids'].append( mch_name ) - + + 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 ): @@ -426,9 +426,9 @@ class Rig: 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 ) ) @@ -436,18 +436,18 @@ class Rig: 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] ): @@ -455,7 +455,7 @@ class Rig: 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'] ] @@ -464,10 +464,10 @@ class Rig: eb[ bone ].parent = eb[ org('face') ] for bone in def_tweaks: - # the def and the matching org bone are parented to their corresponding tweak, + # 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:] ] + 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 ]: @@ -478,10 +478,10 @@ class Rig: # 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' ] @@ -491,11 +491,11 @@ class Rig: 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: @@ -505,30 +505,30 @@ class Rig: # 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 + + eyes = [ + bone for bone in all_bones['ctrls']['eyes'] if 'eyes' not in bone ][0:2] for eye in eyes: @@ -539,17 +539,17 @@ class Rig: eb[ eye_master ].parent = eb[ 'ORG-face' ] # Parent brow.b, eyes mch and lid tweaks and mch bones to masters - tweaks = [ + 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' ] @@ -557,7 +557,7 @@ class Rig: 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'] + eb[ all_bones['ctrls']['nose'].pop() ].parent = eb['MCH-jaw_master.004'] ## Parenting the tweak bones @@ -600,12 +600,12 @@ class Rig: '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' ] @@ -620,14 +620,14 @@ class Rig: 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' ) @@ -649,28 +649,28 @@ class Rig: 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 @@ -684,7 +684,7 @@ class Rig: const.influence = influence elif constraint_type == 'tweak_copyloc': - + const = owner_pb.constraints.new( 'COPY_LOCATION' ) const.target = self.obj const.subtarget = subtarget @@ -692,25 +692,25 @@ class Rig: 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 @@ -721,18 +721,18 @@ class Rig: 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', @@ -780,42 +780,42 @@ class Rig: 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 ) @@ -829,9 +829,9 @@ class Rig: 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 ] ], @@ -853,15 +853,15 @@ class Rig: '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 + # 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' ) @@ -872,7 +872,7 @@ class Rig: '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] @@ -881,7 +881,7 @@ class Rig: # 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 ], @@ -889,12 +889,12 @@ class Rig: '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'] ) @@ -905,16 +905,16 @@ class Rig: 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 @@ -927,33 +927,33 @@ class Rig: 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): @@ -967,58 +967,58 @@ class Rig: 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] + mchs = self.create_mch( + ctrls['ctrls']['jaw'][0], + ctrls['ctrls']['tongue'][0] ) - return { - 'deform' : def_names, - 'ctrls' : ctrls['ctrls'], - 'tweaks' : ctrls['tweaks'], - 'mch' : mchs + 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, + 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, + params.primary_layers_extra = bpy.props.BoolProperty( + name = "primary_layers_extra", + default = True, description = "" ) params.primary_layers = bpy.props.BoolVectorProperty( @@ -1026,9 +1026,9 @@ def add_parameters(params): 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, + params.secondary_layers_extra = bpy.props.BoolProperty( + name = "secondary_layers_extra", + default = True, description = "" ) params.secondary_layers = bpy.props.BoolVectorProperty( @@ -1041,12 +1041,12 @@ def add_parameters(params): 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): @@ -1055,10 +1055,10 @@ def parameters_ui(layout, params): 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="") @@ -2381,10 +2381,10 @@ 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 ), + ( 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) ] diff --git a/rigify/rigs/pitchipoy/super_finger.py b/rigify/legacy/rigs/pitchipoy/super_finger.py similarity index 94% rename from rigify/rigs/pitchipoy/super_finger.py rename to rigify/legacy/rigs/pitchipoy/super_finger.py index 6a9c5f098e0c1e73200f159a87ed95e8f15cef17..86733921e9f074fdf4715bc6c98ddf8794998b21 100644 --- a/rigify/rigs/pitchipoy/super_finger.py +++ b/rigify/legacy/rigs/pitchipoy/super_finger.py @@ -14,58 +14,58 @@ if is_selected(controls): """ 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))) + 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 ) @@ -73,26 +73,26 @@ class Rig: # 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] + 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 @@ -100,7 +100,7 @@ class Rig: 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 @@ -117,19 +117,19 @@ class Rig: else: # The rest ctrl_bone_e.parent = mch_bone_drv_e - ctrl_bone_e.use_connect = False - + 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 + + # 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 ) @@ -138,17 +138,17 @@ class Rig: 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 @@ -159,7 +159,7 @@ class Rig: # 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 @@ -169,31 +169,31 @@ class Rig: 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 @@ -202,7 +202,7 @@ class Rig: 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] @@ -210,19 +210,19 @@ class Rig: # 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 = { @@ -239,7 +239,7 @@ class Rig: "-Z" : { "axis" : 2, "expr" : '-((1-sy)*pi)' } } - + axis = self.params.primary_rotation_axis # Drivers @@ -251,7 +251,7 @@ class Rig: 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] @@ -264,7 +264,7 @@ class Rig: 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' @@ -274,10 +274,10 @@ class Rig: 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: @@ -292,17 +292,17 @@ class Rig: 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 @@ -316,9 +316,9 @@ def parameters_ui(layout, params): """ r = layout.row() r.label(text="Bend rotation axis:") - r.prop(params, "primary_rotation_axis", text="") - - + r.prop(params, "primary_rotation_axis", text="") + + def create_sample(obj): # generated by rigify.utils.write_metarig bpy.ops.object.mode_set(mode='EDIT') @@ -406,9 +406,9 @@ def create_sample(obj): bone.select = True bone.select_head = True bone.select_tail = True - arm.edit_bones.active = bone - - - - - + arm.edit_bones.active = bone + + + + + diff --git a/rigify/rigs/pitchipoy/super_palm.py b/rigify/legacy/rigs/pitchipoy/super_palm.py old mode 100755 new mode 100644 similarity index 100% rename from rigify/rigs/pitchipoy/super_palm.py rename to rigify/legacy/rigs/pitchipoy/super_palm.py diff --git a/rigify/rigs/pitchipoy/super_torso_turbo.py b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py similarity index 92% rename from rigify/rigs/pitchipoy/super_torso_turbo.py rename to rigify/legacy/rigs/pitchipoy/super_torso_turbo.py index b6b7008518d7d6de7bc2175fd3ab62a831242223..e1ff5b0e717a68c181022c2ab1475ec616a16ded 100644 --- a/rigify/rigs/pitchipoy/super_torso_turbo.py +++ b/rigify/legacy/rigs/pitchipoy/super_torso_turbo.py @@ -1,7 +1,7 @@ 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 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 @@ -16,7 +16,7 @@ if is_selected( controls ): """ class Rig: - + def __init__(self, obj, bone_name, params): """ Initialize torso rig and key rig properties """ @@ -59,7 +59,7 @@ class Rig: if len(self.org_bones) <= 4: raise MetarigError( "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name)) - ) + ) def build_bone_structure( self ): @@ -67,14 +67,14 @@ class Rig: 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] @@ -85,8 +85,8 @@ class Rig: return { 'neck' : neck_bones, - 'upper' : upper_torso_bones, - 'lower' : lower_torso_bones, + 'upper' : upper_torso_bones, + 'lower' : lower_torso_bones, 'tail' : tail_bones } @@ -95,13 +95,13 @@ class Rig: 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 + eb.tail[:] = eb.head + tail_vec else: tail_vec = v * self.obj.matrix_world eb.tail[:] = eb.head + tail_vec @@ -114,19 +114,19 @@ class Rig: bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones - - # Create torso control bone + + # 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 @@ -142,28 +142,28 @@ class Rig: '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 ] @@ -179,14 +179,14 @@ class Rig: mch_str = copy_bone( self.obj, neck, make_mechanism_name('STR-neck') ) # Neck MCH rotation - mch_neck = copy_bone( + 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( + mch_head = copy_bone( self.obj, head, make_mechanism_name('ROT-head') ) @@ -204,8 +204,8 @@ class Rig: # 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 ) - + twk_name = copy_bone( self.obj, org(b), twk_name ) + eb[twk_name].length /= 2 twk += [ twk_name ] @@ -223,25 +223,25 @@ class Rig: 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' ) + 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 ) @@ -263,36 +263,36 @@ class Rig: 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 + 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' ) + 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 + 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 ] @@ -315,13 +315,13 @@ class Rig: 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'] ] @@ -343,7 +343,7 @@ class Rig: 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): @@ -358,14 +358,14 @@ class Rig: 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 @@ -374,14 +374,14 @@ class Rig: 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: @@ -408,7 +408,7 @@ class Rig: const = owner_pb.constraints.new( constraint['constraint'] ) const.target = self.obj - # filter contraint props to those that actually exist in the currnet + # 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] ) @@ -419,11 +419,11 @@ class Rig: # head and neck MCH bones for b in [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]: - self.make_constraint( b, { + self.make_constraint( b, { 'constraint' : 'COPY_ROTATION', 'subtarget' : bones['pivot']['ctrl'], } ) - self.make_constraint( b, { + self.make_constraint( b, { 'constraint' : 'COPY_SCALE', 'subtarget' : bones['pivot']['ctrl'], } ) @@ -437,11 +437,11 @@ class Rig: 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'] @@ -452,21 +452,21 @@ class Rig: for j,b in enumerate(mch): if i == 0: nfactor = float( (j + 1) / len( mch ) ) - self.make_constraint( b, { + self.make_constraint( b, { 'constraint' : 'COPY_ROTATION', 'subtarget' : l['ctrl'], 'influence' : nfactor } ) else: - self.make_constraint( b, { + 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', @@ -474,7 +474,7 @@ class Rig: 'owner_space' : 'LOCAL', 'target_space' : 'LOCAL' }) - + # DEF bones deform = bones['def'] tweaks = bones['hips']['tweak'] + bones['chest']['tweak'] @@ -509,13 +509,13 @@ class Rig: 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 @@ -528,13 +528,13 @@ class Rig: 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" @@ -543,13 +543,13 @@ class Rig: 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 @@ -564,7 +564,7 @@ class Rig: # Locks tweaks = bones['neck']['tweak'] + bones['chest']['tweak'] tweaks += bones['hips']['tweak'] - + if 'tail' in bones.keys(): tweaks += bones['tail']['tweak'] @@ -577,39 +577,39 @@ class Rig: # Assigning a widget to torso bone create_cube_widget( - self.obj, - bones['pivot']['ctrl'], - radius = 0.5, + self.obj, + bones['pivot']['ctrl'], + radius = 0.5, bone_transform_name = None ) - + # Assigning widgets to control bones - gen_ctrls = [ - bones['neck']['ctrl_neck'], + 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, + self.obj, bone, - radius = 1.0, - head_tail = 0.5, - with_line = False, + 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, + self.obj, + bones['neck']['ctrl'], + radius = 0.75, + head_tail = 1.0, + with_line = False, bone_transform_name = None ) @@ -617,7 +617,7 @@ class Rig: 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'] ] + hips_widget_loc = pb[ bones['hips']['mch_wgt'] ] if 'tail' in bones.keys(): hips_widget_loc = bones['def'][self.tail_pos -1] @@ -626,13 +626,13 @@ class Rig: # 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 + 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 @@ -682,15 +682,15 @@ class Rig: 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'], + controls_string, + bones['pivot']['ctrl'], 'head_follow', 'neck_follow' )] @@ -721,9 +721,9 @@ def add_parameters( params ): ) # Setting up extra layers for the FK and tweak - params.tweak_extra_layers = bpy.props.BoolProperty( - name = "tweak_extra_layers", - default = True, + params.tweak_extra_layers = bpy.props.BoolProperty( + name = "tweak_extra_layers", + default = True, description = "" ) @@ -736,7 +736,7 @@ def add_parameters( params ): def parameters_ui(layout, params): """ Create the ui for the rig parameters.""" - + r = layout.row() r.prop(params, "neck_pos") @@ -749,7 +749,7 @@ def parameters_ui(layout, params): 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) @@ -785,7 +785,7 @@ def create_sample(obj): 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 @@ -793,7 +793,7 @@ def create_sample(obj): 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 @@ -801,7 +801,7 @@ def create_sample(obj): 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 @@ -809,7 +809,7 @@ def create_sample(obj): 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 @@ -817,7 +817,7 @@ def create_sample(obj): 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 @@ -825,7 +825,7 @@ def create_sample(obj): 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 @@ -833,7 +833,7 @@ def create_sample(obj): 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']] diff --git a/rigify/rigs/pitchipoy/super_widgets.py b/rigify/legacy/rigs/pitchipoy/super_widgets.py similarity index 99% rename from rigify/rigs/pitchipoy/super_widgets.py rename to rigify/legacy/rigs/pitchipoy/super_widgets.py index 8930ba91f66f86f957f02f10ace321eeddc31e8c..aee6c14e9cf04ecdb205577aad89f0ca4886b1f5 100644 --- a/rigify/rigs/pitchipoy/super_widgets.py +++ b/rigify/legacy/rigs/pitchipoy/super_widgets.py @@ -43,7 +43,7 @@ def create_ear_widget(rig, bone_name, size=1.0, bone_transform_name=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() @@ -58,7 +58,7 @@ def create_jaw_widget(rig, bone_name, size=1.0, bone_transform_name=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() @@ -66,21 +66,21 @@ def create_jaw_widget(rig, bone_name, size=1.0, bone_transform_name=None): 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: @@ -132,7 +132,7 @@ def create_hand_widget(rig, bone_name, size=1.0, bone_transform_name=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: + 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 = [] @@ -153,7 +153,7 @@ def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=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() diff --git a/rigify/rigs/pitchipoy/tentacle.py b/rigify/legacy/rigs/pitchipoy/tentacle.py similarity index 92% rename from rigify/rigs/pitchipoy/tentacle.py rename to rigify/legacy/rigs/pitchipoy/tentacle.py index 0d24be161119fe6ea90ef18c94579ba619161e6a..b8d52e88dd77e39d9d5c3ebfc5a6f0a7dbef5503 100644 --- a/rigify/rigs/pitchipoy/tentacle.py +++ b/rigify/legacy/rigs/pitchipoy/tentacle.py @@ -16,17 +16,17 @@ if is_selected( controls ): """ 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)) @@ -39,49 +39,49 @@ class Rig: 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, + self.obj, mch_parent_name, make_mechanism_name( strip_org( org_bones[0] ) ) ) else: mch_bone = copy_bone( - self.obj, + 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], + self.obj, + org_bones[0], "master_" + strip_org( org_bones[0] ) - ) + ) # Make widgets - bpy.ops.object.mode_set(mode ='OBJECT') + 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') @@ -92,8 +92,8 @@ class Rig: name = org_bones[i] ctrl_bone = copy_bone( - self.obj, - name, + self.obj, + name, strip_org(name) ) @@ -104,7 +104,7 @@ class Rig: for ctrl in ctrl_chain: create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5) - + return ctrl_chain @@ -122,19 +122,19 @@ class Rig: name = org_bones[i] tweak_bone = copy_bone( - self.obj, - name, + 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 @@ -157,8 +157,8 @@ class Rig: # Set up tweak bone layers if self.tweak_layers: tweak_pb.bone.layers = self.tweak_layers - - return tweak_chain + + return tweak_chain def make_deform( self ): @@ -171,13 +171,13 @@ class Rig: name = org_bones[i] def_bone = copy_bone( - self.obj, - name, + self.obj, + name, make_deformer_name(strip_org(name)) ) def_chain.append( def_bone ) - + return def_chain @@ -207,7 +207,7 @@ class Rig: 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']: @@ -216,7 +216,7 @@ class Rig: parent = all_bones['control'][ -1 ] else: parent = all_bones['control'][ tweaks.index( tweak ) ] - + eb[ tweak ].parent = eb[ parent ] # Parent deform bones @@ -228,15 +228,15 @@ class Rig: # 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 ] - - + 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'] ] @@ -249,37 +249,37 @@ class Rig: 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 + 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" @@ -298,15 +298,15 @@ class Rig: 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]: @@ -316,7 +316,7 @@ class Rig: con.use_offset = True con.target_space = 'LOCAL' con.owner_space = 'LOCAL' - + def generate(self): bpy.ops.object.mode_set(mode ='EDIT') @@ -326,7 +326,7 @@ class Rig: 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() @@ -341,7 +341,7 @@ class Rig: 'tweak' : tweak_chain, 'deform' : def_chain } - + self.make_constraints( all_bones ) self.parent_bones( all_bones ) @@ -350,7 +350,7 @@ class Rig: all_controls = all_bones['control'] + all_bones['tweak'] # + [ all_bones['master'] ] controls_string = ", ".join(["'" + x + "'" for x in all_controls]) return [script % ( - controls_string, + controls_string, 'rotation_follow', 'scale_follow' )] @@ -361,14 +361,14 @@ def add_parameters(params): RigifyParameters PropertyGroup """ params.make_rotations = bpy.props.BoolProperty( - name = "Rotations", - default = True, + 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", + params.tweak_extra_layers = bpy.props.BoolProperty( + name = "tweak_extra_layers", default = True, description = "" ) @@ -390,7 +390,7 @@ def parameters_ui(layout, params): 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) @@ -400,28 +400,28 @@ def parameters_ui(layout, params): row = col.row(align=True) for i in range( 16, 24 ): # Layers 16-23 - row.prop(params, "tweak_layers", index=i, toggle=True, text="") - + 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.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="") + 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 ), + ( 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) ] @@ -435,7 +435,7 @@ def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None): else: return None -def create_sample(obj): +def create_sample(obj): # generated by rigify.utils.write_metarig bpy.ops.object.mode_set(mode='EDIT') diff --git a/rigify/rigs/spine.py b/rigify/legacy/rigs/spine.py similarity index 100% rename from rigify/rigs/spine.py rename to rigify/legacy/rigs/spine.py diff --git a/rigify/legacy/ui.py b/rigify/legacy/ui.py new file mode 100644 index 0000000000000000000000000000000000000000..bcd8b7be268a21129ab8f4409cc1d42c738e4a6b --- /dev/null +++ b/rigify/legacy/ui.py @@ -0,0 +1,441 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +import bpy +from bpy.props import StringProperty + +from .utils import get_rig_type, MetarigError +from .utils import write_metarig, write_widget +from . import rig_lists +from . import generate + + +class DATA_PT_rigify_buttons(bpy.types.Panel): + bl_label = "Rigify Buttons" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + #bl_options = {'DEFAULT_OPEN'} + + @classmethod + def poll(cls, context): + if not context.armature: + return False + #obj = context.object + #if obj: + # return (obj.mode in {'POSE', 'OBJECT', 'EDIT'}) + #return False + return True + + def draw(self, context): + C = context + layout = self.layout + obj = context.object + id_store = C.window_manager + + if obj.mode in {'POSE', 'OBJECT'}: + layout.operator("pose.rigify_generate", text="Generate") + elif obj.mode == 'EDIT': + # Build types list + collection_name = str(id_store.rigify_collection).replace(" ", "") + + for i in range(0, len(id_store.rigify_types)): + id_store.rigify_types.remove(0) + + for r in rig_lists.rig_list: + # collection = r.split('.')[0] # UNUSED + if collection_name == "All": + a = id_store.rigify_types.add() + a.name = r + elif r.startswith(collection_name + '.'): + a = id_store.rigify_types.add() + a.name = r + elif (collection_name == "None") and ("." not in r): + a = id_store.rigify_types.add() + a.name = r + + ## Rig collection field + #row = layout.row() + #row.prop(id_store, 'rigify_collection', text="Category") + + # Rig type list + row = layout.row() + row.template_list("UI_UL_list", "rigify_types", id_store, "rigify_types", id_store, 'rigify_active_type') + + props = layout.operator("armature.metarig_sample_add", text="Add sample") + props.metarig_type = id_store.rigify_types[id_store.rigify_active_type].name + + +class DATA_PT_rigify_layer_names(bpy.types.Panel): + bl_label = "Rigify Layer Names" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "data" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + if not context.armature: + return False + return True + + def draw(self, context): + layout = self.layout + obj = context.object + arm = obj.data + + # Ensure that the layers exist + if 0: + for i in range(1 + len(arm.rigify_layers), 29): + arm.rigify_layers.add() + else: + # Can't add while drawing, just use button + if len(arm.rigify_layers) < 28: + layout.operator("pose.rigify_layer_init") + return + + # UI + for i, rigify_layer in enumerate(arm.rigify_layers): + # note: rigify_layer == arm.rigify_layers[i] + if (i % 16) == 0: + col = layout.column() + if i == 0: + col.label(text="Top Row:") + else: + col.label(text="Bottom Row:") + if (i % 8) == 0: + col = layout.column(align=True) + row = col.row() + row.prop(arm, "layers", index=i, text="", toggle=True) + split = row.split(percentage=0.8) + split.prop(rigify_layer, "name", text="Layer %d" % (i + 1)) + split.prop(rigify_layer, "row", text="") + + #split.prop(rigify_layer, "column", text="") + + +class BONE_PT_rigify_buttons(bpy.types.Panel): + bl_label = "Rigify Type" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "bone" + #bl_options = {'DEFAULT_OPEN'} + + @classmethod + def poll(cls, context): + if not context.armature or not context.active_pose_bone: + return False + obj = context.object + if obj: + return obj.mode == 'POSE' + return False + + def draw(self, context): + C = context + id_store = C.window_manager + bone = context.active_pose_bone + collection_name = str(id_store.rigify_collection).replace(" ", "") + rig_name = str(context.active_pose_bone.rigify_type).replace(" ", "") + + layout = self.layout + + # Build types list + for i in range(0, len(id_store.rigify_types)): + id_store.rigify_types.remove(0) + + for r in rig_lists.rig_list: + # collection = r.split('.')[0] # UNUSED + if collection_name == "All": + a = id_store.rigify_types.add() + a.name = r + elif r.startswith(collection_name + '.'): + a = id_store.rigify_types.add() + a.name = r + elif collection_name == "None" and len(r.split('.')) == 1: + a = id_store.rigify_types.add() + a.name = r + + # Rig type field + row = layout.row() + row.prop_search(bone, "rigify_type", id_store, "rigify_types", text="Rig type:") + + # Rig type parameters / Rig type non-exist alert + if rig_name != "": + try: + rig = get_rig_type(rig_name) + rig.Rig + except (ImportError, AttributeError): + row = layout.row() + box = row.box() + box.label(text="ALERT: type \"%s\" does not exist!" % rig_name) + else: + try: + rig.parameters_ui + except AttributeError: + col = layout.column() + col.label(text="No options") + else: + col = layout.column() + col.label(text="Options:") + box = layout.box() + rig.parameters_ui(box, bone.rigify_parameters) + + +class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel): + bl_label = "Rigify Dev Tools" + bl_category = 'Tools' + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + + @classmethod + def poll(cls, context): + return context.active_object is not None and context.mode in {'EDIT_ARMATURE','EDIT_MESH'} + + def draw(self, context): + obj = context.active_object + if obj is not None: + if context.mode == 'EDIT_ARMATURE': + r = self.layout.row() + r.operator("armature.rigify_encode_metarig", text="Encode Metarig to Python") + r = self.layout.row() + r.operator("armature.rigify_encode_metarig_sample", text="Encode Sample to Python") + + if context.mode == 'EDIT_MESH': + r = self.layout.row() + r.operator("mesh.rigify_encode_mesh_widget", text="Encode Mesh Widget to Python") + +#~ class INFO_MT_armature_metarig_add(bpy.types.Menu): + #~ bl_idname = "INFO_MT_armature_metarig_add" + #~ bl_label = "Meta-Rig" + + #~ def draw(self, context): + #~ import rigify + + #~ layout = self.layout + #~ layout.operator_context = 'INVOKE_REGION_WIN' + + #~ for submodule_type in rigify.get_submodule_types(): + #~ text = bpy.path.display_name(submodule_type) + #~ layout.operator("pose.metarig_sample_add", text=text, icon='OUTLINER_OB_ARMATURE').metarig_type = submodule_type + + +def rigify_report_exception(operator, exception): + import traceback + import sys + import os + # find the module name where the error happened + # hint, this is the metarig type! + exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() + fn = traceback.extract_tb(exceptionTraceback)[-1][0] + fn = os.path.basename(fn) + fn = os.path.splitext(fn)[0] + message = [] + if fn.startswith("__"): + message.append("Incorrect armature...") + else: + message.append("Incorrect armature for type '%s'" % fn) + message.append(exception.message) + + message.reverse() # XXX - stupid! menu's are upside down! + + operator.report({'INFO'}, '\n'.join(message)) + + +class LayerInit(bpy.types.Operator): + """Initialize armature rigify layers""" + + bl_idname = "pose.rigify_layer_init" + bl_label = "Add Rigify Layers" + bl_options = {'UNDO'} + + def execute(self, context): + obj = context.object + arm = obj.data + for i in range(1 + len(arm.rigify_layers), 29): + arm.rigify_layers.add() + return {'FINISHED'} + + +class Generate(bpy.types.Operator): + """Generates a rig from the active metarig armature""" + + bl_idname = "pose.rigify_generate" + bl_label = "Rigify Generate Rig" + bl_options = {'UNDO'} + + def execute(self, context): + import importlib + importlib.reload(generate) + + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + generate.generate_rig(context, context.object) + except MetarigError as rig_exception: + rigify_report_exception(self, rig_exception) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + + return {'FINISHED'} + + +class Sample(bpy.types.Operator): + """Create a sample metarig to be modified before generating """ \ + """the final rig""" + + bl_idname = "armature.metarig_sample_add" + bl_label = "Add a sample metarig for a rig type" + bl_options = {'UNDO'} + + metarig_type = StringProperty( + name="Type", + description="Name of the rig type to generate a sample of", + maxlen=128, + ) + + def execute(self, context): + if context.mode == 'EDIT_ARMATURE' and self.metarig_type != "": + use_global_undo = context.user_preferences.edit.use_global_undo + context.user_preferences.edit.use_global_undo = False + try: + rig = get_rig_type(self.metarig_type) + create_sample = rig.create_sample + except (ImportError, AttributeError): + raise Exception("rig type '" + self.metarig_type + "' has no sample.") + else: + create_sample(context.active_object) + finally: + context.user_preferences.edit.use_global_undo = use_global_undo + bpy.ops.object.mode_set(mode='EDIT') + + return {'FINISHED'} + + +class EncodeMetarig(bpy.types.Operator): + """ Creates Python code that will generate the selected metarig. + """ + bl_idname = "armature.rigify_encode_metarig" + bl_label = "Rigify Encode Metarig" + bl_options = {'UNDO'} + + @classmethod + def poll(self, context): + return context.mode == 'EDIT_ARMATURE' + + def execute(self, context): + name = "metarig.py" + + if name in bpy.data.texts: + text_block = bpy.data.texts[name] + text_block.clear() + else: + text_block = bpy.data.texts.new(name) + + text = write_metarig(context.active_object, layers=True, func_name="create") + text_block.write(text) + bpy.ops.object.mode_set(mode='EDIT') + + return {'FINISHED'} + + +class EncodeMetarigSample(bpy.types.Operator): + """ Creates Python code that will generate the selected metarig + as a sample. + """ + bl_idname = "armature.rigify_encode_metarig_sample" + bl_label = "Rigify Encode Metarig Sample" + bl_options = {'UNDO'} + + @classmethod + def poll(self, context): + return context.mode == 'EDIT_ARMATURE' + + def execute(self, context): + name = "metarig_sample.py" + + if name in bpy.data.texts: + text_block = bpy.data.texts[name] + text_block.clear() + else: + text_block = bpy.data.texts.new(name) + + text = write_metarig(context.active_object, layers=False, func_name="create_sample") + text_block.write(text) + bpy.ops.object.mode_set(mode='EDIT') + + return {'FINISHED'} + + +class EncodeWidget(bpy.types.Operator): + """ Creates Python code that will generate the selected metarig. + """ + bl_idname = "mesh.rigify_encode_mesh_widget" + bl_label = "Rigify Encode Widget" + bl_options = {'UNDO'} + + @classmethod + def poll(self, context): + return context.mode == 'EDIT_MESH' + + def execute(self, context): + name = "widget.py" + + if name in bpy.data.texts: + text_block = bpy.data.texts[name] + text_block.clear() + else: + text_block = bpy.data.texts.new(name) + + text = write_widget(context.active_object) + text_block.write(text) + bpy.ops.object.mode_set(mode='EDIT') + + return {'FINISHED'} + + +#menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE')) + +#from bl_ui import space_info # ensure the menu is loaded first + +def register(): + bpy.utils.register_class(DATA_PT_rigify_layer_names) + bpy.utils.register_class(DATA_PT_rigify_buttons) + bpy.utils.register_class(BONE_PT_rigify_buttons) + bpy.utils.register_class(VIEW3D_PT_tools_rigify_dev) + bpy.utils.register_class(LayerInit) + bpy.utils.register_class(Generate) + bpy.utils.register_class(Sample) + bpy.utils.register_class(EncodeMetarig) + bpy.utils.register_class(EncodeMetarigSample) + bpy.utils.register_class(EncodeWidget) + #space_info.INFO_MT_armature_add.append(ui.menu_func) + + +def unregister(): + bpy.utils.unregister_class(DATA_PT_rigify_layer_names) + bpy.utils.unregister_class(DATA_PT_rigify_buttons) + bpy.utils.unregister_class(BONE_PT_rigify_buttons) + bpy.utils.unregister_class(VIEW3D_PT_tools_rigify_dev) + bpy.utils.unregister_class(LayerInit) + bpy.utils.unregister_class(Generate) + bpy.utils.unregister_class(Sample) + bpy.utils.unregister_class(EncodeMetarig) + bpy.utils.unregister_class(EncodeMetarigSample) + bpy.utils.unregister_class(EncodeWidget) diff --git a/rigify/legacy/utils.py b/rigify/legacy/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..7e20e76e527345d0018c0bfead619090138ef2cf --- /dev/null +++ b/rigify/legacy/utils.py @@ -0,0 +1,939 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +import bpy +import importlib +import importlib +import math +import random +import time +from mathutils import Vector, Matrix +from rna_prop_ui import rna_idprop_ui_prop_get + +RIG_DIR = "rigs" # Name of the directory where rig types are kept +METARIG_DIR = "metarigs" # Name of the directory where metarigs are kept + +ORG_PREFIX = "ORG-" # Prefix of original bones. +MCH_PREFIX = "MCH-" # Prefix of mechanism bones. +DEF_PREFIX = "DEF-" # Prefix of deformation bones. +WGT_PREFIX = "WGT-" # Prefix for widget objects +ROOT_NAME = "root" # Name of the root bone. + +WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer. + +MODULE_NAME = "rigify" # Windows/Mac blender is weird, so __package__ doesn't work + + +#======================================================================= +# Error handling +#======================================================================= +class MetarigError(Exception): + """ Exception raised for errors. + """ + def __init__(self, message): + self.message = message + + def __str__(self): + return repr(self.message) + + +#======================================================================= +# Name manipulation +#======================================================================= +def org_name(name): + """ Returns the name with ORG_PREFIX stripped from it. + """ + if name.startswith(ORG_PREFIX): + return name[len(ORG_PREFIX):] + else: + return name + + +def strip_org(name): + """ Returns the name with ORG_PREFIX stripped from it. + """ + if name.startswith(ORG_PREFIX): + return name[len(ORG_PREFIX):] + else: + return name +org_name = strip_org + + +def org(name): + """ Prepends the ORG_PREFIX to a name if it doesn't already have + it, and returns it. + """ + if name.startswith(ORG_PREFIX): + return name + else: + return ORG_PREFIX + name +make_original_name = org + + +def mch(name): + """ Prepends the MCH_PREFIX to a name if it doesn't already have + it, and returns it. + """ + if name.startswith(MCH_PREFIX): + return name + else: + return MCH_PREFIX + name +make_mechanism_name = mch + + +def deformer(name): + """ Prepends the DEF_PREFIX to a name if it doesn't already have + it, and returns it. + """ + if name.startswith(DEF_PREFIX): + return name + else: + return DEF_PREFIX + name +make_deformer_name = deformer + + +def insert_before_lr(name, text): + if name[-1] in ['l', 'L', 'r', 'R'] and name[-2] in ['.', '-', '_']: + return name[:-2] + text + name[-2:] + else: + return name + text + + +#======================= +# Bone manipulation +#======================= +def new_bone(obj, bone_name): + """ Adds a new bone to the given armature object. + Returns the resulting bone's name. + """ + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + edit_bone = obj.data.edit_bones.new(bone_name) + name = edit_bone.name + edit_bone.head = (0, 0, 0) + edit_bone.tail = (0, 1, 0) + edit_bone.roll = 0 + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='EDIT') + return name + else: + raise MetarigError("Can't add new bone '%s' outside of edit mode" % bone_name) + +def copy_bone_simple(obj, bone_name, assign_name=''): + """ Makes a copy of the given bone in the given armature object. + but only copies head, tail positions and roll. Does not + address parenting either. + """ + #if bone_name not in obj.data.bones: + if bone_name not in obj.data.edit_bones: + raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name) + + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + if assign_name == '': + assign_name = bone_name + # Copy the edit bone + edit_bone_1 = obj.data.edit_bones[bone_name] + edit_bone_2 = obj.data.edit_bones.new(assign_name) + bone_name_1 = bone_name + bone_name_2 = edit_bone_2.name + + # Copy edit bone attributes + edit_bone_2.layers = list(edit_bone_1.layers) + + edit_bone_2.head = Vector(edit_bone_1.head) + edit_bone_2.tail = Vector(edit_bone_1.tail) + edit_bone_2.roll = edit_bone_1.roll + + return bone_name_2 + else: + raise MetarigError("Cannot copy bones outside of edit mode") + +def copy_bone(obj, bone_name, assign_name=''): + """ Makes a copy of the given bone in the given armature object. + Returns the resulting bone's name. + """ + #if bone_name not in obj.data.bones: + if bone_name not in obj.data.edit_bones: + raise MetarigError("copy_bone(): bone '%s' not found, cannot copy it" % bone_name) + + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + if assign_name == '': + assign_name = bone_name + # Copy the edit bone + edit_bone_1 = obj.data.edit_bones[bone_name] + edit_bone_2 = obj.data.edit_bones.new(assign_name) + bone_name_1 = bone_name + bone_name_2 = edit_bone_2.name + + edit_bone_2.parent = edit_bone_1.parent + edit_bone_2.use_connect = edit_bone_1.use_connect + + # Copy edit bone attributes + edit_bone_2.layers = list(edit_bone_1.layers) + + edit_bone_2.head = Vector(edit_bone_1.head) + edit_bone_2.tail = Vector(edit_bone_1.tail) + edit_bone_2.roll = edit_bone_1.roll + + edit_bone_2.use_inherit_rotation = edit_bone_1.use_inherit_rotation + edit_bone_2.use_inherit_scale = edit_bone_1.use_inherit_scale + edit_bone_2.use_local_location = edit_bone_1.use_local_location + + edit_bone_2.use_deform = edit_bone_1.use_deform + edit_bone_2.bbone_segments = edit_bone_1.bbone_segments + edit_bone_2.bbone_in = edit_bone_1.bbone_in + edit_bone_2.bbone_out = edit_bone_1.bbone_out + + bpy.ops.object.mode_set(mode='OBJECT') + + # Get the pose bones + pose_bone_1 = obj.pose.bones[bone_name_1] + pose_bone_2 = obj.pose.bones[bone_name_2] + + # Copy pose bone attributes + pose_bone_2.rotation_mode = pose_bone_1.rotation_mode + pose_bone_2.rotation_axis_angle = tuple(pose_bone_1.rotation_axis_angle) + pose_bone_2.rotation_euler = tuple(pose_bone_1.rotation_euler) + pose_bone_2.rotation_quaternion = tuple(pose_bone_1.rotation_quaternion) + + pose_bone_2.lock_location = tuple(pose_bone_1.lock_location) + pose_bone_2.lock_scale = tuple(pose_bone_1.lock_scale) + pose_bone_2.lock_rotation = tuple(pose_bone_1.lock_rotation) + pose_bone_2.lock_rotation_w = pose_bone_1.lock_rotation_w + pose_bone_2.lock_rotations_4d = pose_bone_1.lock_rotations_4d + + # Copy custom properties + for key in pose_bone_1.keys(): + if key != "_RNA_UI" \ + and key != "rigify_parameters" \ + and key != "rigify_type": + prop1 = rna_idprop_ui_prop_get(pose_bone_1, key, create=False) + prop2 = rna_idprop_ui_prop_get(pose_bone_2, key, create=True) + pose_bone_2[key] = pose_bone_1[key] + for key in prop1.keys(): + prop2[key] = prop1[key] + + bpy.ops.object.mode_set(mode='EDIT') + + return bone_name_2 + else: + raise MetarigError("Cannot copy bones outside of edit mode") + + +def flip_bone(obj, bone_name): + """ Flips an edit bone. + """ + if bone_name not in obj.data.bones: + raise MetarigError("flip_bone(): bone '%s' not found, cannot copy it" % bone_name) + + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + bone = obj.data.edit_bones[bone_name] + head = Vector(bone.head) + tail = Vector(bone.tail) + bone.tail = head + tail + bone.head = tail + bone.tail = head + else: + raise MetarigError("Cannot flip bones outside of edit mode") + + +def put_bone(obj, bone_name, pos): + """ Places a bone at the given position. + """ + if bone_name not in obj.data.bones: + raise MetarigError("put_bone(): bone '%s' not found, cannot move it" % bone_name) + + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + bone = obj.data.edit_bones[bone_name] + + delta = pos - bone.head + bone.translate(delta) + else: + raise MetarigError("Cannot 'put' bones outside of edit mode") + + +def make_nonscaling_child(obj, bone_name, location, child_name_postfix=""): + """ Takes the named bone and creates a non-scaling child of it at + the given location. The returned bone (returned by name) is not + a true child, but behaves like one sans inheriting scaling. + + It is intended as an intermediate construction to prevent rig types + from scaling with their parents. The named bone is assumed to be + an ORG bone. + """ + if bone_name not in obj.data.bones: + raise MetarigError("make_nonscaling_child(): bone '%s' not found, cannot copy it" % bone_name) + + if obj == bpy.context.active_object and bpy.context.mode == 'EDIT_ARMATURE': + # Create desired names for bones + name1 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_ch"))) + name2 = make_mechanism_name(strip_org(insert_before_lr(bone_name, child_name_postfix + "_ns_intr"))) + + # Create bones + child = copy_bone(obj, bone_name, name1) + intermediate_parent = copy_bone(obj, bone_name, name2) + + # Get edit bones + eb = obj.data.edit_bones + child_e = eb[child] + intrpar_e = eb[intermediate_parent] + + # Parenting + child_e.use_connect = False + child_e.parent = None + + intrpar_e.use_connect = False + intrpar_e.parent = eb[bone_name] + + # Positioning + child_e.length *= 0.5 + intrpar_e.length *= 0.25 + + put_bone(obj, child, location) + put_bone(obj, intermediate_parent, location) + + # Object mode + bpy.ops.object.mode_set(mode='OBJECT') + pb = obj.pose.bones + + # Add constraints + con = pb[child].constraints.new('COPY_LOCATION') + con.name = "parent_loc" + con.target = obj + con.subtarget = intermediate_parent + + con = pb[child].constraints.new('COPY_ROTATION') + con.name = "parent_loc" + con.target = obj + con.subtarget = intermediate_parent + + bpy.ops.object.mode_set(mode='EDIT') + + return child + else: + raise MetarigError("Cannot make nonscaling child outside of edit mode") + + +#============================================= +# Widget creation +#============================================= + +def obj_to_bone(obj, rig, bone_name): + """ Places an object at the location/rotation/scale of the given bone. + """ + if bpy.context.mode == 'EDIT_ARMATURE': + raise MetarigError("obj_to_bone(): does not work while in edit mode") + + bone = rig.data.bones[bone_name] + + mat = rig.matrix_world * bone.matrix_local + + obj.location = mat.to_translation() + + obj.rotation_mode = 'XYZ' + obj.rotation_euler = mat.to_euler() + + scl = mat.to_scale() + scl_avg = (scl[0] + scl[1] + scl[2]) / 3 + obj.scale = (bone.length * scl_avg), (bone.length * scl_avg), (bone.length * scl_avg) + + +def create_circle_polygon(number_verts, axis, radius=1.0, head_tail=0.0): + """ Creates a basic circle around of an axis selected. + number_verts: number of vertices of the poligon + axis: axis normal to the circle + radius: the radius of the circle + head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail) + """ + verts = [] + edges = [] + angle = 2 * math.pi / number_verts + i = 0 + + assert(axis in 'XYZ') + + while i < (number_verts): + a = math.cos(i * angle) + b = math.sin(i * angle) + + if axis == 'X': + verts.append((head_tail, a * radius, b * radius)) + elif axis == 'Y': + verts.append((a * radius, head_tail, b * radius)) + elif axis == 'Z': + verts.append((a * radius, b * radius, head_tail)) + + if i < (number_verts - 1): + edges.append((i , i + 1)) + + i += 1 + + edges.append((0, number_verts - 1)) + + return verts, edges + + +def create_widget(rig, bone_name, bone_transform_name=None): + """ Creates an empty widget object for a bone, and returns the object. + """ + if bone_transform_name is None: + bone_transform_name = bone_name + + obj_name = WGT_PREFIX + bone_name + scene = bpy.context.scene + + # Check if it already exists in the scene + if obj_name in scene.objects: + # Move object to bone position, in case it changed + obj = scene.objects[obj_name] + obj_to_bone(obj, rig, bone_transform_name) + + return None + else: + # Delete object if it exists in blend data but not scene data. + # This is necessary so we can then create the object without + # name conflicts. + if obj_name in bpy.data.objects: + bpy.data.objects[obj_name].user_clear() + bpy.data.objects.remove(bpy.data.objects[obj_name]) + + # Create mesh object + mesh = bpy.data.meshes.new(obj_name) + obj = bpy.data.objects.new(obj_name, mesh) + scene.objects.link(obj) + + # Move object to bone position and set layers + obj_to_bone(obj, rig, bone_transform_name) + obj.layers = WGT_LAYERS + + return obj + + +# Common Widgets + +def create_line_widget(rig, bone_name, bone_transform_name=None): + """ Creates a basic line widget, a line that spans the length of the bone. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + mesh = obj.data + mesh.from_pydata([(0, 0, 0), (0, 1, 0)], [(0, 1)], []) + mesh.update() + + +def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0, with_line=False, bone_transform_name=None): + """ Creates a basic circle widget, a circle around the y-axis. + radius: the radius of the circle + head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail) + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts, edges = create_circle_polygon(32, 'Y', radius, head_tail) + + if with_line: + edges.append((8, 24)) + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + return obj + else: + return None + + +def create_cube_widget(rig, bone_name, radius=0.5, bone_transform_name=None): + """ Creates a basic cube widget. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + r = radius + verts = [(r, r, r), (r, -r, r), (-r, -r, r), (-r, r, r), (r, r, -r), (r, -r, -r), (-r, -r, -r), (-r, r, -r)] + edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)] + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_sphere_widget(rig, bone_name, bone_transform_name=None): + """ Creates a basic sphere widget, three pependicular overlapping circles. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts_x, edges_x = create_circle_polygon(16, 'X', 0.5) + verts_y, edges_y = create_circle_polygon(16, 'Y', 0.5) + verts_z, edges_z = create_circle_polygon(16, 'Z', 0.5) + + verts = verts_x + verts_y + verts_z + + edges = [ + (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), + (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), + (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), + (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (16, 31), + (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), + (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47), + ] + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_limb_widget(rig, bone_name, bone_transform_name=None): + """ Creates a basic limb widget, a line that spans the length of the + bone, with a circle around the center. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts, edges = create_circle_polygon(32, "Y", 0.25, 0.5) + verts.append((0, 0, 0)) + verts.append((0, 1, 0)) + edges.append((32, 33)) + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_bone_widget(rig, bone_name, bone_transform_name=None): + """ Creates a basic bone widget, a simple obolisk-esk shape. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.04, 1.0, -0.04), (0.1, 0.0, -0.1), (-0.1, 0.0, -0.1), (-0.04, 1.0, -0.04), (0.04, 1.0, 0.04), (0.1, 0.0, 0.1), (-0.1, 0.0, 0.1), (-0.04, 1.0, 0.04)] + edges = [(1, 2), (0, 1), (0, 3), (2, 3), (4, 5), (5, 6), (6, 7), (4, 7), (1, 5), (0, 4), (2, 6), (3, 7)] + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_compass_widget(rig, bone_name, bone_transform_name=None): + """ Creates a compass-shaped widget. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts, edges = create_circle_polygon(32, "Z", 1.0, 0.0) + i = 0 + for v in verts: + if i in {0, 8, 16, 24}: + verts[i] = (v[0] * 1.2, v[1] * 1.2, v[2]) + i += 1 + + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +def create_root_widget(rig, bone_name, bone_transform_name=None): + """ Creates a widget for the root bone. + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj is not None: + verts = [(0.7071067690849304, 0.7071067690849304, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (-0.7071067690849304, 0.7071067690849304, 0.0), (-0.7071067690849304, -0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (-0.8314696550369263, 0.5555701851844788, 0.0), (-0.8314696550369263, -0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9238795042037964, -0.3826834261417389, 0.0), (-0.9238795042037964, 0.3826834261417389, 0.0), (-0.9238795042037964, -0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (0.9807852506637573, -0.19509035348892212, 0.0), (-0.9807852506637573, 0.19509035348892212, 0.0), (-0.9807852506637573, -0.19509035348892212, 0.0), (0.19509197771549225, 0.9807849526405334, 0.0), (0.19509197771549225, -0.9807849526405334, 0.0), (-0.19509197771549225, 0.9807849526405334, 0.0), (-0.19509197771549225, -0.9807849526405334, 0.0), (0.3826850652694702, 0.9238788485527039, 0.0), (0.3826850652694702, -0.9238788485527039, 0.0), (-0.3826850652694702, 0.9238788485527039, 0.0), (-0.3826850652694702, -0.9238788485527039, 0.0), (0.5555717945098877, 0.8314685821533203, 0.0), (0.5555717945098877, -0.8314685821533203, 0.0), (-0.5555717945098877, 0.8314685821533203, 0.0), (-0.5555717945098877, -0.8314685821533203, 0.0), (0.19509197771549225, 1.2807848453521729, 0.0), (0.19509197771549225, -1.2807848453521729, 0.0), (-0.19509197771549225, 1.2807848453521729, 0.0), (-0.19509197771549225, -1.2807848453521729, 0.0), (1.280785322189331, 0.19509035348892212, 0.0), (1.280785322189331, -0.19509035348892212, 0.0), (-1.280785322189331, 0.19509035348892212, 0.0), (-1.280785322189331, -0.19509035348892212, 0.0), (0.3950919806957245, 1.2807848453521729, 0.0), (0.3950919806957245, -1.2807848453521729, 0.0), (-0.3950919806957245, 1.2807848453521729, 0.0), (-0.3950919806957245, -1.2807848453521729, 0.0), (1.280785322189331, 0.39509034156799316, 0.0), (1.280785322189331, -0.39509034156799316, 0.0), (-1.280785322189331, 0.39509034156799316, 0.0), (-1.280785322189331, -0.39509034156799316, 0.0), (0.0, 1.5807849168777466, 0.0), (0.0, -1.5807849168777466, 0.0), (1.5807852745056152, 0.0, 0.0), (-1.5807852745056152, 0.0, 0.0)] + edges = [(0, 4), (1, 5), (2, 6), (3, 7), (4, 8), (5, 9), (6, 10), (7, 11), (8, 12), (9, 13), (10, 14), (11, 15), (16, 20), (17, 21), (18, 22), (19, 23), (20, 24), (21, 25), (22, 26), (23, 27), (0, 24), (1, 25), (2, 26), (3, 27), (16, 28), (17, 29), (18, 30), (19, 31), (12, 32), (13, 33), (14, 34), (15, 35), (28, 36), (29, 37), (30, 38), (31, 39), (32, 40), (33, 41), (34, 42), (35, 43), (36, 44), (37, 45), (38, 44), (39, 45), (40, 46), (41, 46), (42, 47), (43, 47)] + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() + + +#============================================= +# Math +#============================================= + +def angle_on_plane(plane, vec1, vec2): + """ Return the angle between two vectors projected onto a plane. + """ + plane.normalize() + vec1 = vec1 - (plane * (vec1.dot(plane))) + vec2 = vec2 - (plane * (vec2.dot(plane))) + vec1.normalize() + vec2.normalize() + + # Determine the angle + angle = math.acos(max(-1.0, min(1.0, vec1.dot(vec2)))) + + if angle < 0.00001: # close enough to zero that sign doesn't matter + return angle + + # Determine the sign of the angle + vec3 = vec2.cross(vec1) + vec3.normalize() + sign = vec3.dot(plane) + if sign >= 0: + sign = 1 + else: + sign = -1 + + return angle * sign + + +def align_bone_roll(obj, bone1, bone2): + """ Aligns the roll of two bones. + """ + bone1_e = obj.data.edit_bones[bone1] + bone2_e = obj.data.edit_bones[bone2] + + bone1_e.roll = 0.0 + + # Get the directions the bones are pointing in, as vectors + y1 = bone1_e.y_axis + x1 = bone1_e.x_axis + y2 = bone2_e.y_axis + x2 = bone2_e.x_axis + + # Get the shortest axis to rotate bone1 on to point in the same direction as bone2 + axis = y1.cross(y2) + axis.normalize() + + # Angle to rotate on that shortest axis + angle = y1.angle(y2) + + # Create rotation matrix to make bone1 point in the same direction as bone2 + rot_mat = Matrix.Rotation(angle, 3, axis) + + # Roll factor + x3 = rot_mat * x1 + dot = x2 * x3 + if dot > 1.0: + dot = 1.0 + elif dot < -1.0: + dot = -1.0 + roll = math.acos(dot) + + # Set the roll + bone1_e.roll = roll + + # Check if we rolled in the right direction + x3 = rot_mat * bone1_e.x_axis + check = x2 * x3 + + # If not, reverse + if check < 0.9999: + bone1_e.roll = -roll + + +def align_bone_x_axis(obj, bone, vec): + """ Rolls the bone to align its x-axis as closely as possible to + the given vector. + Must be in edit mode. + """ + bone_e = obj.data.edit_bones[bone] + + vec = vec.cross(bone_e.y_axis) + vec.normalize() + + dot = max(-1.0, min(1.0, bone_e.z_axis.dot(vec))) + angle = math.acos(dot) + + bone_e.roll += angle + + dot1 = bone_e.z_axis.dot(vec) + + bone_e.roll -= angle * 2 + + dot2 = bone_e.z_axis.dot(vec) + + if dot1 > dot2: + bone_e.roll += angle * 2 + + +def align_bone_z_axis(obj, bone, vec): + """ Rolls the bone to align its z-axis as closely as possible to + the given vector. + Must be in edit mode. + """ + bone_e = obj.data.edit_bones[bone] + + vec = bone_e.y_axis.cross(vec) + vec.normalize() + + dot = max(-1.0, min(1.0, bone_e.x_axis.dot(vec))) + angle = math.acos(dot) + + bone_e.roll += angle + + dot1 = bone_e.x_axis.dot(vec) + + bone_e.roll -= angle * 2 + + dot2 = bone_e.x_axis.dot(vec) + + if dot1 > dot2: + bone_e.roll += angle * 2 + + +#============================================= +# Misc +#============================================= + +def copy_attributes(a, b): + keys = dir(a) + for key in keys: + if not key.startswith("_") \ + and not key.startswith("error_") \ + and key != "group" \ + and key != "is_valid" \ + and key != "rna_type" \ + and key != "bl_rna": + try: + setattr(b, key, getattr(a, key)) + except AttributeError: + pass + + +def get_rig_type(rig_type): + """ Fetches a rig module by name, and returns it. + """ + name = "legacy.%s.%s" % (RIG_DIR, rig_type) + submod = importlib.import_module(name, package=MODULE_NAME) + importlib.reload(submod) + return submod + + +def get_metarig_module(metarig_name): + """ Fetches a rig module by name, and returns it. + """ + name = "legacy.%s.%s" % (METARIG_DIR, metarig_name) + submod = importlib.import_module(name, package=MODULE_NAME) + importlib.reload(submod) + return submod + + +def connected_children_names(obj, bone_name): + """ Returns a list of bone names (in order) of the bones that form a single + connected chain starting with the given bone as a parent. + If there is a connected branch, the list stops there. + """ + bone = obj.data.bones[bone_name] + names = [] + + while True: + connects = 0 + con_name = "" + + for child in bone.children: + if child.use_connect: + connects += 1 + con_name = child.name + + if connects == 1: + names += [con_name] + bone = obj.data.bones[con_name] + else: + break + + return names + + +def has_connected_children(bone): + """ Returns true/false whether a bone has connected children or not. + """ + t = False + for b in bone.children: + t = t or b.use_connect + return t + + +def get_layers(layers): + """ Does it's best to exctract a set of layers from any data thrown at it. + """ + if type(layers) == int: + return [x == layers for x in range(0, 32)] + elif type(layers) == str: + s = layers.split(",") + l = [] + for i in s: + try: + l += [int(float(i))] + except ValueError: + pass + return [x in l for x in range(0, 32)] + elif type(layers) == tuple or type(layers) == list: + return [x in layers for x in range(0, 32)] + else: + try: + list(layers) + except TypeError: + pass + else: + return [x in layers for x in range(0, 32)] + + +def write_metarig(obj, layers=False, func_name="create"): + """ + Write a metarig as a python script, this rig is to have all info needed for + generating the real rig with rigify. + """ + code = [] + + code.append("import bpy\n\n") + + code.append("def %s(obj):" % func_name) + code.append(" # generated by rigify.utils.write_metarig") + bpy.ops.object.mode_set(mode='EDIT') + code.append(" bpy.ops.object.mode_set(mode='EDIT')") + code.append(" arm = obj.data") + + arm = obj.data + + # Rigify layer layout info + if layers and len(arm.rigify_layers) > 0: + code.append("\n for i in range(" + str(len(arm.rigify_layers)) + "):") + code.append(" arm.rigify_layers.add()\n") + + for i in range(len(arm.rigify_layers)): + name = arm.rigify_layers[i].name + row = arm.rigify_layers[i].row + code.append(' arm.rigify_layers[' + str(i) + '].name = "' + name + '"') + code.append(' arm.rigify_layers[' + str(i) + '].row = ' + str(row)) + + # write parents first + bones = [(len(bone.parent_recursive), bone.name) for bone in arm.edit_bones] + bones.sort(key=lambda item: item[0]) + bones = [item[1] for item in bones] + + code.append("\n bones = {}\n") + + for bone_name in bones: + bone = arm.edit_bones[bone_name] + code.append(" bone = arm.edit_bones.new(%r)" % bone.name) + code.append(" bone.head[:] = %.4f, %.4f, %.4f" % bone.head.to_tuple(4)) + code.append(" bone.tail[:] = %.4f, %.4f, %.4f" % bone.tail.to_tuple(4)) + code.append(" bone.roll = %.4f" % bone.roll) + code.append(" bone.use_connect = %s" % str(bone.use_connect)) + if bone.parent: + code.append(" bone.parent = arm.edit_bones[bones[%r]]" % bone.parent.name) + code.append(" bones[%r] = bone.name" % bone.name) + + bpy.ops.object.mode_set(mode='OBJECT') + code.append("") + code.append(" bpy.ops.object.mode_set(mode='OBJECT')") + + # Rig type and other pose properties + for bone_name in bones: + pbone = obj.pose.bones[bone_name] + + code.append(" pbone = obj.pose.bones[bones[%r]]" % bone_name) + code.append(" pbone.rigify_type = %r" % pbone.rigify_type) + code.append(" pbone.lock_location = %s" % str(tuple(pbone.lock_location))) + code.append(" pbone.lock_rotation = %s" % str(tuple(pbone.lock_rotation))) + code.append(" pbone.lock_rotation_w = %s" % str(pbone.lock_rotation_w)) + code.append(" pbone.lock_scale = %s" % str(tuple(pbone.lock_scale))) + code.append(" pbone.rotation_mode = %r" % pbone.rotation_mode) + if layers: + code.append(" pbone.bone.layers = %s" % str(list(pbone.bone.layers))) + # Rig type parameters + for param_name in pbone.rigify_parameters.keys(): + param = getattr(pbone.rigify_parameters, param_name) + if str(type(param)) == "<class 'bpy_prop_array'>": + param = list(param) + if type(param) == str: + param = '"' + param + '"' + code.append(" try:") + code.append(" pbone.rigify_parameters.%s = %s" % (param_name, str(param))) + code.append(" except AttributeError:") + code.append(" pass") + + code.append("\n bpy.ops.object.mode_set(mode='EDIT')") + code.append(" for bone in arm.edit_bones:") + code.append(" bone.select = False") + code.append(" bone.select_head = False") + code.append(" bone.select_tail = False") + + code.append(" for b in bones:") + code.append(" bone = arm.edit_bones[bones[b]]") + code.append(" bone.select = True") + code.append(" bone.select_head = True") + code.append(" bone.select_tail = True") + code.append(" arm.edit_bones.active = bone") + + # Set appropriate layers visible + if layers: + # Find what layers have bones on them + active_layers = [] + for bone_name in bones: + bone = obj.data.bones[bone_name] + for i in range(len(bone.layers)): + if bone.layers[i]: + if i not in active_layers: + active_layers.append(i) + active_layers.sort() + + code.append("\n arm.layers = [(x in " + str(active_layers) + ") for x in range(" + str(len(arm.layers)) + ")]") + + code.append('\nif __name__ == "__main__":') + code.append(" " + func_name + "(bpy.context.active_object)") + + return "\n".join(code) + + +def write_widget(obj): + """ Write a mesh object as a python script for widget use. + """ + script = "" + script += "def create_thing_widget(rig, bone_name, size=1.0, bone_transform_name=None):\n" + script += " obj = create_widget(rig, bone_name, bone_transform_name)\n" + script += " if obj is not None:\n" + + # Vertices + if len(obj.data.vertices) > 0: + script += " verts = [" + for v in obj.data.vertices: + script += "(" + str(v.co[0]) + "*size, " + str(v.co[1]) + "*size, " + str(v.co[2]) + "*size), " + script += "]\n" + + # Edges + if len(obj.data.edges) > 0: + script += " edges = [" + for e in obj.data.edges: + script += "(" + str(e.vertices[0]) + ", " + str(e.vertices[1]) + "), " + script += "]\n" + + # Faces + if len(obj.data.polygons) > 0: + script += " faces = [" + for f in obj.data.polygons: + script += "(" + for v in f.vertices: + script += str(v) + ", " + script += "), " + script += "]\n" + + # Build mesh + script += "\n mesh = obj.data\n" + script += " mesh.from_pydata(verts, edges, faces)\n" + script += " mesh.update()\n" + script += " mesh.update()\n" + script += " return obj\n" + script += " else:\n" + script += " return None\n" + + return script + + +def random_id(length=8): + """ Generates a random alphanumeric id string. + """ + tlength = int(length / 2) + rlength = int(length / 2) + int(length % 2) + + chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] + text = "" + for i in range(0, rlength): + text += random.choice(chars) + text += str(hex(int(time.time())))[2:][-tlength:].rjust(tlength, '0')[::-1] + return text diff --git a/rigify/metarigs/human.py b/rigify/metarigs/human.py index 7adc03d7e74da57e196bf5746a253d773a56cefc..4c13644141e46b1c3f1550e48a3fb908063d6530 100644 --- a/rigify/metarigs/human.py +++ b/rigify/metarigs/human.py @@ -1,23 +1,3 @@ -# ##### 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 ##### - -# <pep8 compliant> - import bpy def create(obj): @@ -25,102 +5,118 @@ def create(obj): bpy.ops.object.mode_set(mode='EDIT') arm = obj.data - for i in range(28): + for i in range(29): arm.rigify_layers.add() - arm.rigify_layers[0].name = "head" + arm.rigify_layers[0].name = "Face" arm.rigify_layers[0].row = 1 - arm.rigify_layers[1].name = " " - arm.rigify_layers[1].row = 1 - arm.rigify_layers[2].name = "Torso" + arm.rigify_layers[1].name = "Face (Primary)" + arm.rigify_layers[1].row = 2 + arm.rigify_layers[2].name = "Face (Secondary)" arm.rigify_layers[2].row = 2 - arm.rigify_layers[3].name = " " - arm.rigify_layers[3].row = 1 - arm.rigify_layers[4].name = "Fingers" - arm.rigify_layers[4].row = 3 - arm.rigify_layers[5].name = "(Tweak)" - arm.rigify_layers[5].row = 3 - arm.rigify_layers[6].name = "Arm.L (FK)" - arm.rigify_layers[6].row = 4 + arm.rigify_layers[3].name = "Torso" + arm.rigify_layers[3].row = 3 + arm.rigify_layers[4].name = "Torso (Tweak)" + arm.rigify_layers[4].row = 4 + arm.rigify_layers[5].name = "Fingers" + arm.rigify_layers[5].row = 5 + arm.rigify_layers[6].name = "Fingers (Tweak)" + arm.rigify_layers[6].row = 6 arm.rigify_layers[7].name = "Arm.L (IK)" - arm.rigify_layers[7].row = 5 - arm.rigify_layers[8].name = "Arm.L (Tweak)" - arm.rigify_layers[8].row = 6 - arm.rigify_layers[9].name = "Arm.R (FK)" - arm.rigify_layers[9].row = 4 + arm.rigify_layers[7].row = 7 + arm.rigify_layers[8].name = "Arm.L (FK)" + arm.rigify_layers[8].row = 8 + arm.rigify_layers[9].name = "Arm.L (Tweak)" + arm.rigify_layers[9].row = 9 arm.rigify_layers[10].name = "Arm.R (IK)" - arm.rigify_layers[10].row = 5 - arm.rigify_layers[11].name = "Arm.R (Tweak)" - arm.rigify_layers[11].row = 6 - arm.rigify_layers[12].name = "Leg.L (FK)" - arm.rigify_layers[12].row = 7 + arm.rigify_layers[10].row = 7 + arm.rigify_layers[11].name = "Arm.R (FK)" + arm.rigify_layers[11].row = 8 + arm.rigify_layers[12].name = "Arm.R (Tweak)" + arm.rigify_layers[12].row = 9 arm.rigify_layers[13].name = "Leg.L (IK)" - arm.rigify_layers[13].row = 8 - arm.rigify_layers[14].name = "Leg.L (Tweak)" - arm.rigify_layers[14].row = 9 - arm.rigify_layers[15].name = "Leg.R (FK)" - arm.rigify_layers[15].row = 7 + arm.rigify_layers[13].row = 10 + arm.rigify_layers[14].name = "Leg.L (FK)" + arm.rigify_layers[14].row = 11 + arm.rigify_layers[15].name = "Leg.L (Tweak)" + arm.rigify_layers[15].row = 12 arm.rigify_layers[16].name = "Leg.R (IK)" - arm.rigify_layers[16].row = 8 - arm.rigify_layers[17].name = "Leg.R (Tweak)" - arm.rigify_layers[17].row = 9 - arm.rigify_layers[18].name = " " - arm.rigify_layers[18].row = 1 - arm.rigify_layers[19].name = " " + arm.rigify_layers[16].row = 10 + arm.rigify_layers[17].name = "Leg.R (FK)" + arm.rigify_layers[17].row = 11 + arm.rigify_layers[18].name = "Leg.R (Tweak)" + arm.rigify_layers[18].row = 12 + arm.rigify_layers[19].name = "" arm.rigify_layers[19].row = 1 - arm.rigify_layers[20].name = " " + arm.rigify_layers[20].name = "" arm.rigify_layers[20].row = 1 - arm.rigify_layers[21].name = " " + arm.rigify_layers[21].name = "" arm.rigify_layers[21].row = 1 - arm.rigify_layers[22].name = " " + arm.rigify_layers[22].name = "" arm.rigify_layers[22].row = 1 - arm.rigify_layers[23].name = " " + arm.rigify_layers[23].name = "" arm.rigify_layers[23].row = 1 - arm.rigify_layers[24].name = " " + arm.rigify_layers[24].name = "" arm.rigify_layers[24].row = 1 - arm.rigify_layers[25].name = " " + arm.rigify_layers[25].name = "" arm.rigify_layers[25].row = 1 - arm.rigify_layers[26].name = " " + arm.rigify_layers[26].name = "" arm.rigify_layers[26].row = 1 - arm.rigify_layers[27].name = " " + arm.rigify_layers[27].name = "" arm.rigify_layers[27].row = 1 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 bones = {} - bone = arm.edit_bones.new('hips') + bone = arm.edit_bones.new('spine') bone.head[:] = 0.0000, 0.0552, 1.0099 - bone.tail[:] = 0.0000, 0.0172, 1.1837 + bone.tail[:] = 0.0000, 0.0172, 1.1573 bone.roll = 0.0000 bone.use_connect = False - bones['hips'] = bone.name - bone = arm.edit_bones.new('spine') - bone.head[:] = 0.0000, 0.0172, 1.1837 - bone.tail[:] = 0.0000, 0.0004, 1.3418 + 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['hips']] - bones['spine'] = bone.name + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('pelvis.L') + bone.head[:] = 0.0000, 0.0552, 1.0099 + bone.tail[:] = 0.1112, -0.0451, 1.1533 + bone.roll = -1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.L'] = bone.name + bone = arm.edit_bones.new('pelvis.R') + bone.head[:] = -0.0000, 0.0552, 1.0099 + bone.tail[:] = -0.1112, -0.0451, 1.1533 + bone.roll = 1.0756 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine']] + bones['pelvis.R'] = bone.name bone = arm.edit_bones.new('thigh.L') bone.head[:] = 0.0980, 0.0124, 1.0720 bone.tail[:] = 0.0980, -0.0286, 0.5372 bone.roll = 0.0000 bone.use_connect = False - bone.parent = arm.edit_bones[bones['hips']] + bone.parent = arm.edit_bones[bones['spine']] bones['thigh.L'] = bone.name bone = arm.edit_bones.new('thigh.R') bone.head[:] = -0.0980, 0.0124, 1.0720 bone.tail[:] = -0.0980, -0.0286, 0.5372 bone.roll = 0.0000 bone.use_connect = False - bone.parent = arm.edit_bones[bones['hips']] + bone.parent = arm.edit_bones[bones['spine']] bones['thigh.R'] = bone.name - bone = arm.edit_bones.new('chest') - bone.head[:] = 0.0000, 0.0004, 1.3418 - bone.tail[:] = 0.0000, 0.0114, 1.6582 + 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']] - bones['chest'] = bone.name + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name bone = arm.edit_bones.new('shin.L') bone.head[:] = 0.0980, -0.0286, 0.5372 bone.tail[:] = 0.0980, 0.0162, 0.0852 @@ -135,27 +131,13 @@ def create(obj): bone.use_connect = True bone.parent = arm.edit_bones[bones['thigh.R']] bones['shin.R'] = bone.name - bone = arm.edit_bones.new('neck') - bone.head[:] = 0.0000, 0.0114, 1.6582 - bone.tail[:] = 0.0000, -0.0247, 1.7813 + 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 = False - bone.parent = arm.edit_bones[bones['chest']] - bones['neck'] = bone.name - bone = arm.edit_bones.new('shoulder.L') - bone.head[:] = 0.0183, -0.0684, 1.6051 - bone.tail[:] = 0.1694, 0.0205, 1.6050 - bone.roll = 0.0004 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['chest']] - bones['shoulder.L'] = bone.name - bone = arm.edit_bones.new('shoulder.R') - bone.head[:] = -0.0183, -0.0684, 1.6051 - bone.tail[:] = -0.1694, 0.0205, 1.6050 - bone.roll = -0.0004 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['chest']] - bones['shoulder.R'] = bone.name + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name bone = arm.edit_bones.new('foot.L') bone.head[:] = 0.0980, 0.0162, 0.0852 bone.tail[:] = 0.0980, -0.0934, 0.0167 @@ -163,13 +145,6 @@ def create(obj): bone.use_connect = True bone.parent = arm.edit_bones[bones['shin.L']] bones['foot.L'] = bone.name - bone = arm.edit_bones.new('heel.L') - bone.head[:] = 0.0980, 0.0162, 0.0852 - bone.tail[:] = 0.0980, 0.0882, -0.0000 - bone.roll = -3.1416 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['shin.L']] - bones['heel.L'] = bone.name bone = arm.edit_bones.new('foot.R') bone.head[:] = -0.0980, 0.0162, 0.0852 bone.tail[:] = -0.0980, -0.0934, 0.0167 @@ -177,34 +152,41 @@ def create(obj): bone.use_connect = True bone.parent = arm.edit_bones[bones['shin.R']] bones['foot.R'] = bone.name - bone = arm.edit_bones.new('heel.R') - bone.head[:] = -0.0980, 0.0162, 0.0852 - bone.tail[:] = -0.0980, 0.0882, -0.0000 - bone.roll = 3.1416 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['shin.R']] - bones['heel.R'] = bone.name - bone = arm.edit_bones.new('head') - bone.head[:] = 0.0000, -0.0247, 1.7813 - bone.tail[:] = 0.0000, -0.0247, 1.9347 + bone = arm.edit_bones.new('spine.004') + bone.head[:] = 0.0000, 0.0114, 1.6582 + bone.tail[:] = 0.0000, -0.013, 1.7197 bone.roll = 0.0000 bone.use_connect = True - bone.parent = arm.edit_bones[bones['neck']] - bones['head'] = bone.name - bone = arm.edit_bones.new('upper_arm.L') - bone.head[:] = 0.1953, 0.0267, 1.5846 - bone.tail[:] = 0.4424, 0.0885, 1.4491 - bone.roll = 2.0691 + bone.parent = arm.edit_bones[bones['spine.003']] + bones['spine.004'] = bone.name + bone = arm.edit_bones.new('shoulder.L') + bone.head[:] = 0.0183, -0.0684, 1.6051 + bone.tail[:] = 0.1694, 0.0205, 1.6050 + bone.roll = 0.0004 bone.use_connect = False - bone.parent = arm.edit_bones[bones['shoulder.L']] - bones['upper_arm.L'] = bone.name - bone = arm.edit_bones.new('upper_arm.R') - bone.head[:] = -0.1953, 0.0267, 1.5846 - bone.tail[:] = -0.4424, 0.0885, 1.4491 - bone.roll = -2.0691 + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.L'] = bone.name + bone = arm.edit_bones.new('shoulder.R') + bone.head[:] = -0.0183, -0.0684, 1.6051 + bone.tail[:] = -0.1694, 0.0205, 1.6050 + bone.roll = -0.0004 bone.use_connect = False - bone.parent = arm.edit_bones[bones['shoulder.R']] - bones['upper_arm.R'] = bone.name + bone.parent = arm.edit_bones[bones['spine.003']] + bones['shoulder.R'] = bone.name + bone = arm.edit_bones.new('breast.L') + bone.head[:] = 0.1184, 0.0485, 1.4596 + bone.tail[:] = 0.1184, -0.0907, 1.4596 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['breast.L'] = bone.name + bone = arm.edit_bones.new('breast.R') + bone.head[:] = -0.1184, 0.0485, 1.4596 + bone.tail[:] = -0.1184, -0.0907, 1.4596 + bone.roll = -0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.003']] + bones['breast.R'] = bone.name bone = arm.edit_bones.new('toe.L') bone.head[:] = 0.0980, -0.0934, 0.0167 bone.tail[:] = 0.0980, -0.1606, 0.0167 @@ -213,11 +195,11 @@ def create(obj): bone.parent = arm.edit_bones[bones['foot.L']] bones['toe.L'] = bone.name bone = arm.edit_bones.new('heel.02.L') - bone.head[:] = 0.0600, 0.0000, 0.0000 - bone.tail[:] = 0.1400, 0.0000, 0.0000 + bone.head[:] = 0.0600, 0.0459, 0.0000 + bone.tail[:] = 0.1400, 0.0459, 0.0000 bone.roll = 0.0000 bone.use_connect = False - bone.parent = arm.edit_bones[bones['heel.L']] + bone.parent = arm.edit_bones[bones['foot.L']] bones['heel.02.L'] = bone.name bone = arm.edit_bones.new('toe.R') bone.head[:] = -0.0980, -0.0934, 0.0167 @@ -227,40 +209,222 @@ def create(obj): bone.parent = arm.edit_bones[bones['foot.R']] bones['toe.R'] = bone.name bone = arm.edit_bones.new('heel.02.R') - bone.head[:] = -0.0600, 0.0000, 0.0000 - bone.tail[:] = -0.1400, 0.0000, 0.0000 - bone.roll = 0.0000 + bone.head[:] = -0.0600, 0.0459, 0.0000 + bone.tail[:] = -0.1400, 0.0459, 0.0000 + bone.roll = -0.0000 bone.use_connect = False - bone.parent = arm.edit_bones[bones['heel.R']] + bone.parent = arm.edit_bones[bones['foot.R']] bones['heel.02.R'] = bone.name + bone = arm.edit_bones.new('spine.005') + bone.head[:] = 0.0000, -0.013, 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('upper_arm.L') + bone.head[:] = 0.1953, 0.0267, 1.5846 + bone.tail[:] = 0.4424, 0.0885, 1.4491 + bone.roll = 2.0724 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.L']] + bones['upper_arm.L'] = bone.name + bone = arm.edit_bones.new('upper_arm.R') + bone.head[:] = -0.1953, 0.0267, 1.5846 + bone.tail[:] = -0.4424, 0.0885, 1.4491 + bone.roll = -2.0724 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['shoulder.R']] + bones['upper_arm.R'] = 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 bone = arm.edit_bones.new('forearm.L') bone.head[:] = 0.4424, 0.0885, 1.4491 bone.tail[:] = 0.6594, 0.0492, 1.3061 - bone.roll = 2.1459 + 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('forearm.R') bone.head[:] = -0.4424, 0.0885, 1.4491 bone.tail[:] = -0.6594, 0.0492, 1.3061 - bone.roll = -2.1459 + bone.roll = -2.1535 bone.use_connect = True bone.parent = arm.edit_bones[bones['upper_arm.R']] bones['forearm.R'] = bone.name + bone = arm.edit_bones.new('face') + bone.head[:] = 0.0000, -0.0247, 1.7813 + bone.tail[:] = 0.0000, -0.0247, 1.8725 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['spine.006']] + bones['face'] = bone.name bone = arm.edit_bones.new('hand.L') bone.head[:] = 0.6594, 0.0492, 1.3061 bone.tail[:] = 0.7234, 0.0412, 1.2585 - bone.roll = -2.4946 + bone.roll = 2.2103 bone.use_connect = True bone.parent = arm.edit_bones[bones['forearm.L']] bones['hand.L'] = bone.name bone = arm.edit_bones.new('hand.R') bone.head[:] = -0.6594, 0.0492, 1.3061 bone.tail[:] = -0.7234, 0.0412, 1.2585 - bone.roll = 2.4946 + bone.roll = -2.2103 bone.use_connect = True bone.parent = arm.edit_bones[bones['forearm.R']] bones['hand.R'] = bone.name + bone = arm.edit_bones.new('nose') + bone.head[:] = 0.0000, -0.1536, 1.8978 + bone.tail[:] = 0.0000, -0.1834, 1.8589 + 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.1710, 1.8140 + bone.tail[:] = 0.0195, -0.1656, 1.8146 + 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.1667, 1.7978 + bone.tail[:] = 0.0185, -0.1585, 1.8028 + 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.0945, 1.7439 + bone.tail[:] = 0.0000, -0.1519, 1.7392 + 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.0919, -0.0309, 1.8622 + bone.tail[:] = 0.0989, -0.0336, 1.9017 + 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.0919, -0.0309, 1.8622 + bone.tail[:] = -0.0989, -0.0336, 1.9017 + 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.1710, 1.8140 + bone.tail[:] = -0.0195, -0.1656, 1.8146 + 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.1667, 1.7978 + bone.tail[:] = -0.0185, -0.1585, 1.8028 + 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.0791, -0.1237, 1.9020 + bone.tail[:] = 0.0704, -0.1349, 1.9078 + 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.0768, -0.1218, 1.8947 + bone.tail[:] = 0.0678, -0.1356, 1.8995 + bone.roll = -0.2079 + 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.0791, -0.1237, 1.9020 + bone.tail[:] = -0.0704, -0.1349, 1.9078 + 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.0768, -0.1218, 1.8947 + bone.tail[:] = -0.0678, -0.1356, 1.8995 + bone.roll = 0.2079 + 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.0168, -0.1325, 1.9704 + bone.tail[:] = 0.0215, -0.1546, 1.9144 + 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.0168, -0.1325, 1.9704 + bone.tail[:] = -0.0215, -0.1546, 1.9144 + 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.0516, -0.1209, 1.8941 + bone.tail[:] = 0.0516, -0.1451, 1.8941 + 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.0516, -0.1209, 1.8941 + bone.tail[:] = -0.0516, -0.1451, 1.8941 + 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.0848, -0.0940, 1.8870 + bone.tail[:] = 0.0565, -0.1430, 1.8517 + 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.0848, -0.0940, 1.8870 + bone.tail[:] = -0.0565, -0.1430, 1.8517 + 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.1568, 1.8214 + bone.tail[:] = 0.0000, -0.1112, 1.8214 + 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.1500, 1.7892 + bone.tail[:] = 0.0000, -0.1043, 1.7892 + 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.1354, 1.7946 + bone.tail[:] = 0.0000, -0.1101, 1.8002 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['face']] + bones['tongue'] = bone.name bone = arm.edit_bones.new('palm.01.L') bone.head[:] = 0.6921, 0.0224, 1.2882 bone.tail[:] = 0.7464, 0.0051, 1.2482 @@ -317,11 +481,130 @@ def create(obj): bone.use_connect = False bone.parent = arm.edit_bones[bones['hand.R']] bones['palm.04.R'] = bone.name + bone = arm.edit_bones.new('nose.001') + bone.head[:] = 0.0000, -0.1834, 1.8589 + bone.tail[:] = 0.0000, -0.1965, 1.8450 + 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.0195, -0.1656, 1.8146 + bone.tail[:] = 0.0352, -0.1494, 1.8074 + 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.0185, -0.1585, 1.8028 + bone.tail[:] = 0.0352, -0.1494, 1.8074 + 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.1519, 1.7392 + bone.tail[:] = 0.0000, -0.1634, 1.7692 + 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.0989, -0.0336, 1.9017 + bone.tail[:] = 0.1200, -0.0088, 1.9074 + 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.0989, -0.0336, 1.9017 + bone.tail[:] = -0.1200, -0.0088, 1.9074 + 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.0195, -0.1656, 1.8146 + bone.tail[:] = -0.0352, -0.1494, 1.8074 + 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.0185, -0.1585, 1.8028 + bone.tail[:] = -0.0352, -0.1494, 1.8074 + 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.0704, -0.1349, 1.9078 + bone.tail[:] = 0.0577, -0.1427, 1.9093 + 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.0678, -0.1356, 1.8995 + bone.tail[:] = 0.0550, -0.1436, 1.9022 + bone.roll = 0.1837 + 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.0704, -0.1349, 1.9078 + bone.tail[:] = -0.0577, -0.1427, 1.9093 + 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.0678, -0.1356, 1.8995 + bone.tail[:] = -0.0550, -0.1436, 1.9022 + bone.roll = -0.1837 + 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.0479, -0.1174, 1.9756 + bone.tail[:] = 0.0588, -0.1421, 1.9255 + 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.0479, -0.1174, 1.9756 + bone.tail[:] = -0.0588, -0.1421, 1.9255 + 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.0565, -0.1430, 1.8517 + bone.tail[:] = 0.0188, -0.1448, 1.8822 + bone.roll = 0.1387 + 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.0565, -0.1430, 1.8517 + bone.tail[:] = -0.0188, -0.1448, 1.8822 + bone.roll = -0.1387 + 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.1101, 1.8002 + bone.tail[:] = 0.0000, -0.0761, 1.7949 + 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('f_index.01.L') bone.head[:] = 0.7464, 0.0051, 1.2482 bone.tail[:] = 0.7718, 0.0013, 1.2112 bone.roll = -2.0315 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.01.L']] bones['f_index.01.L'] = bone.name bone = arm.edit_bones.new('thumb.01.L') @@ -335,28 +618,28 @@ def create(obj): bone.head[:] = 0.7518, 0.0277, 1.2487 bone.tail[:] = 0.7762, 0.0234, 1.2058 bone.roll = -2.0067 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.02.L']] bones['f_middle.01.L'] = bone.name bone = arm.edit_bones.new('f_ring.01.L') bone.head[:] = 0.7540, 0.0521, 1.2482 bone.tail[:] = 0.7715, 0.0499, 1.2070 bone.roll = -2.0082 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.03.L']] bones['f_ring.01.L'] = bone.name bone = arm.edit_bones.new('f_pinky.01.L') bone.head[:] = 0.7528, 0.0763, 1.2428 bone.tail[:] = 0.7589, 0.0765, 1.2156 bone.roll = -1.9749 - bone.use_connect = True + 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_index.01.R') bone.head[:] = -0.7464, 0.0051, 1.2482 bone.tail[:] = -0.7718, 0.0012, 1.2112 bone.roll = 2.0315 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.01.R']] bones['f_index.01.R'] = bone.name bone = arm.edit_bones.new('thumb.01.R') @@ -370,23 +653,114 @@ def create(obj): bone.head[:] = -0.7518, 0.0277, 1.2487 bone.tail[:] = -0.7762, 0.0233, 1.2058 bone.roll = 2.0067 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.02.R']] bones['f_middle.01.R'] = bone.name bone = arm.edit_bones.new('f_ring.01.R') bone.head[:] = -0.7540, 0.0521, 1.2482 bone.tail[:] = -0.7715, 0.0499, 1.2070 bone.roll = 2.0082 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.03.R']] bones['f_ring.01.R'] = bone.name bone = arm.edit_bones.new('f_pinky.01.R') bone.head[:] = -0.7528, 0.0763, 1.2428 bone.tail[:] = -0.7589, 0.0765, 1.2156 bone.roll = 1.9749 - bone.use_connect = True + bone.use_connect = False bone.parent = arm.edit_bones[bones['palm.04.R']] bones['f_pinky.01.R'] = bone.name + bone = arm.edit_bones.new('nose.002') + bone.head[:] = 0.0000, -0.1965, 1.8450 + bone.tail[:] = 0.0000, -0.1854, 1.8402 + 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.1634, 1.7692 + bone.tail[:] = 0.0000, -0.1599, 1.7909 + 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.1200, -0.0088, 1.9074 + bone.tail[:] = 0.1206, -0.0101, 1.8695 + 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.1200, -0.0088, 1.9074 + bone.tail[:] = -0.1206, -0.0101, 1.8695 + 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.0577, -0.1427, 1.9093 + bone.tail[:] = 0.0388, -0.1418, 1.9069 + bone.roll = 0.0847 + 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.0550, -0.1436, 1.9022 + bone.tail[:] = 0.0425, -0.1427, 1.8987 + bone.roll = -0.0940 + 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.0577, -0.1427, 1.9093 + bone.tail[:] = -0.0388, -0.1418, 1.9069 + bone.roll = -0.0847 + 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.0550, -0.1436, 1.9022 + bone.tail[:] = -0.0425, -0.1427, 1.8987 + bone.roll = 0.0940 + 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.0719, -0.0940, 1.9717 + bone.tail[:] = 0.0830, -0.1213, 1.9164 + 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.0719, -0.0940, 1.9717 + bone.tail[:] = -0.0830, -0.1213, 1.9164 + 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.0188, -0.1448, 1.8822 + bone.tail[:] = 0.0176, -0.1627, 1.8429 + bone.roll = 0.0997 + 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.0188, -0.1448, 1.8822 + bone.tail[:] = -0.0176, -0.1627, 1.8429 + bone.roll = -0.0997 + 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.0761, 1.7949 + bone.tail[:] = 0.0000, -0.0538, 1.7673 + 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('f_index.02.L') bone.head[:] = 0.7718, 0.0013, 1.2112 bone.tail[:] = 0.7840, -0.0003, 1.1858 @@ -457,6 +831,83 @@ def create(obj): bone.use_connect = True bone.parent = arm.edit_bones[bones['f_pinky.01.R']] bones['f_pinky.02.R'] = bone.name + bone = arm.edit_bones.new('nose.003') + bone.head[:] = 0.0000, -0.1854, 1.8402 + bone.tail[:] = 0.0000, -0.1706, 1.8393 + 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.1206, -0.0101, 1.8695 + bone.tail[:] = 0.1010, -0.0347, 1.8422 + 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.1206, -0.0101, 1.8695 + bone.tail[:] = -0.1010, -0.0347, 1.8422 + 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.0388, -0.1418, 1.9069 + bone.tail[:] = 0.0221, -0.1397, 1.8950 + bone.roll = 0.1405 + 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.0425, -0.1427, 1.8987 + bone.tail[:] = 0.0262, -0.1418, 1.8891 + bone.roll = 0.2194 + 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.0388, -0.1418, 1.9069 + bone.tail[:] = -0.0221, -0.1397, 1.8950 + bone.roll = -0.1405 + 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.0425, -0.1427, 1.8987 + bone.tail[:] = -0.0262, -0.1418, 1.8891 + bone.roll = -0.2194 + 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.0873, -0.0597, 1.9523 + bone.tail[:] = 0.0926, -0.0625, 1.8738 + bone.roll = -0.0913 + 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.0873, -0.0597, 1.9523 + bone.tail[:] = -0.0926, -0.0625, 1.8738 + bone.roll = 0.0913 + 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.0176, -0.1627, 1.8429 + bone.tail[:] = 0.0000, -0.1965, 1.8450 + 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.0176, -0.1627, 1.8429 + bone.tail[:] = -0.0000, -0.1965, 1.8450 + 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('f_index.03.L') bone.head[:] = 0.7840, -0.0003, 1.1858 bone.tail[:] = 0.7892, 0.0006, 1.1636 @@ -527,42 +978,277 @@ def create(obj): bone.use_connect = True bone.parent = arm.edit_bones[bones['f_pinky.02.R']] bones['f_pinky.03.R'] = bone.name + bone = arm.edit_bones.new('nose.004') + bone.head[:] = 0.0000, -0.1706, 1.8393 + bone.tail[:] = 0.0000, -0.1698, 1.8244 + 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.1010, -0.0347, 1.8422 + bone.tail[:] = 0.0919, -0.0309, 1.8622 + 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.1010, -0.0347, 1.8422 + bone.tail[:] = -0.0919, -0.0309, 1.8622 + 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.0262, -0.1418, 1.8891 + bone.tail[:] = 0.0393, -0.1425, 1.8854 + bone.roll = 0.0756 + 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.0262, -0.1418, 1.8891 + bone.tail[:] = -0.0393, -0.1425, 1.8854 + bone.roll = -0.0756 + 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.0926, -0.0625, 1.8738 + bone.tail[:] = 0.0783, -0.0689, 1.7975 + bone.roll = -0.0899 + 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.0926, -0.0625, 1.8738 + bone.tail[:] = -0.0783, -0.0689, 1.7975 + bone.roll = 0.0899 + 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.0393, -0.1425, 1.8854 + bone.tail[:] = 0.0553, -0.1418, 1.8833 + bone.roll = 0.1015 + 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.0393, -0.1425, 1.8854 + bone.tail[:] = -0.0553, -0.1418, 1.8833 + bone.roll = -0.1015 + 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.0783, -0.0689, 1.7975 + bone.tail[:] = 0.0387, -0.1315, 1.7536 + bone.roll = 0.1223 + 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.0783, -0.0689, 1.7975 + bone.tail[:] = -0.0387, -0.1315, 1.7536 + bone.roll = -0.1223 + 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.0553, -0.1418, 1.8833 + bone.tail[:] = 0.0694, -0.1351, 1.8889 + bone.roll = -0.0748 + 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.0553, -0.1418, 1.8833 + bone.tail[:] = -0.0694, -0.1351, 1.8889 + bone.roll = 0.0748 + 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.0387, -0.1315, 1.7536 + bone.tail[:] = 0.0352, -0.1494, 1.8074 + bone.roll = -0.2078 + 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.0387, -0.1315, 1.7536 + bone.tail[:] = -0.0352, -0.1494, 1.8074 + bone.roll = 0.2078 + 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.0694, -0.1351, 1.8889 + bone.tail[:] = 0.0768, -0.1218, 1.8947 + bone.roll = -0.0085 + 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.0694, -0.1351, 1.8889 + bone.tail[:] = -0.0768, -0.1218, 1.8947 + bone.roll = 0.0085 + 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.0352, -0.1494, 1.8074 + bone.tail[:] = 0.0736, -0.1216, 1.8243 + 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.0352, -0.1494, 1.8074 + bone.tail[:] = -0.0736, -0.1216, 1.8243 + 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.0736, -0.1216, 1.8243 + bone.tail[:] = 0.0848, -0.0940, 1.8870 + 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.0736, -0.1216, 1.8243 + bone.tail[:] = -0.0848, -0.0940, 1.8870 + 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.0848, -0.0940, 1.8870 + bone.tail[:] = 0.0830, -0.1213, 1.9164 + 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.0848, -0.0940, 1.8870 + bone.tail[:] = -0.0830, -0.1213, 1.9164 + 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.0830, -0.1213, 1.9164 + bone.tail[:] = 0.0588, -0.1421, 1.9255 + 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.0830, -0.1213, 1.9164 + bone.tail[:] = -0.0588, -0.1421, 1.9255 + 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.0588, -0.1421, 1.9255 + bone.tail[:] = 0.0215, -0.1546, 1.9144 + 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.0588, -0.1421, 1.9255 + bone.tail[:] = -0.0215, -0.1546, 1.9144 + 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.0215, -0.1546, 1.9144 + bone.tail[:] = 0.0000, -0.1536, 1.8978 + 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.0215, -0.1546, 1.9144 + bone.tail[:] = 0.0000, -0.1536, 1.8978 + 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['hips']] - pbone.rigify_type = 'spine' + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'spines.super_spine' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' - pbone.bone.layers = [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, False, False] + pbone.bone.layers = [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, False] try: pbone.rigify_parameters.chain_bone_controls = "1, 2, 3" except AttributeError: pass - pbone = obj.pose.bones[bones['spine']] + 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.bone.layers = [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, False, False] + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['pelvis.L']] + pbone.rigify_type = 'basic.super_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 = 'YXZ' + pbone.bone.layers = [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, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['pelvis.R']] + pbone.rigify_type = 'basic.super_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 = 'YXZ' + pbone.bone.layers = [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, False] + try: + pbone.rigify_parameters.make_control = False + except AttributeError: + pass pbone = obj.pose.bones[bones['thigh.L']] - pbone.rigify_type = 'biped.leg' - pbone.lock_location = (True, True, True) + pbone.rigify_type = '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' - pbone.bone.layers = [False, False, False, 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] + pbone.bone.layers = [False, False, False, False, 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] 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, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.ik_layers = [False, False, False, False, False, 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] except AttributeError: pass try: @@ -570,23 +1256,35 @@ def create(obj): except AttributeError: pass try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, 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] + pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, 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] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "leg" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, 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] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, 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] except AttributeError: pass pbone = obj.pose.bones[bones['thigh.R']] - pbone.rigify_type = 'biped.leg' - pbone.lock_location = (True, True, True) + pbone.rigify_type = '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' - pbone.bone.layers = [False, False, False, False, False, False, 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] + pbone.bone.layers = [False, False, False, False, False, False, False, 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] 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, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.ik_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass try: @@ -594,593 +1292,1425 @@ def create(obj): except AttributeError: pass try: - pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone.rigify_parameters.hose_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] except AttributeError: pass - pbone = obj.pose.bones[bones['chest']] - pbone.rigify_type = '' - pbone.lock_location = (False, False, False) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.layers = [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, False, False] - pbone = obj.pose.bones[bones['shin.L']] + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, 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, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False] + except AttributeError: + pass + try: + pbone.rigify_parameters.limb_type = "leg" + except AttributeError: + pass + pbone = obj.pose.bones[bones['spine.002']] pbone.rigify_type = '' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' - pbone.bone.layers = [False, False, False, 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] - pbone = obj.pose.bones[bones['shin.R']] + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['shin.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.bone.layers = [False, False, False, False, False, False, 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] - pbone = obj.pose.bones[bones['neck']] - pbone.rigify_type = 'neck_short' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - pbone = obj.pose.bones[bones['shoulder.L']] - pbone.rigify_type = 'basic.copy' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.layers = [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, False, False] - pbone = obj.pose.bones[bones['shoulder.R']] - pbone.rigify_type = 'basic.copy' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.layers = [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, False, False] - pbone = obj.pose.bones[bones['foot.L']] + pbone.bone.layers = [False, False, False, False, 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] + pbone = obj.pose.bones[bones['shin.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.bone.layers = [False, False, False, 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] - pbone = obj.pose.bones[bones['heel.L']] + pbone.bone.layers = [False, False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['spine.003']] pbone.rigify_type = '' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' - pbone.bone.layers = [False, False, False, 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] - pbone = obj.pose.bones[bones['foot.R']] + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['foot.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.bone.layers = [False, False, False, False, False, False, 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] - pbone = obj.pose.bones[bones['heel.R']] + pbone.bone.layers = [False, False, False, False, 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] + pbone = obj.pose.bones[bones['foot.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.bone.layers = [False, False, False, False, False, False, 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] - pbone = obj.pose.bones[bones['head']] + pbone.bone.layers = [False, False, False, False, False, False, False, 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] + 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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] - pbone = obj.pose.bones[bones['upper_arm.L']] - pbone.rigify_type = 'biped.arm' - pbone.lock_location = (True, True, True) + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['shoulder.L']] + pbone.rigify_type = 'basic.super_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' - pbone.bone.layers = [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, False, False] - try: - pbone.rigify_parameters.separate_ik_layers = True - except AttributeError: - pass - try: - pbone.rigify_parameters.ik_layers = [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, False] - except AttributeError: - pass - try: - pbone.rigify_parameters.separate_hose_layers = True - except AttributeError: - pass + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False] try: - pbone.rigify_parameters.hose_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] + pbone.rigify_parameters.make_widget = False except AttributeError: pass - pbone = obj.pose.bones[bones['upper_arm.R']] - pbone.rigify_type = 'biped.arm' - pbone.lock_location = (True, True, True) + pbone = obj.pose.bones[bones['shoulder.R']] + pbone.rigify_type = 'basic.super_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' - pbone.bone.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] - 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, False, False, True, 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 + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False] try: - pbone.rigify_parameters.hose_layers = [False, False, 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] + pbone.rigify_parameters.make_widget = False except AttributeError: pass - pbone = obj.pose.bones[bones['toe.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.bone.layers = [False, False, False, 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] - pbone = obj.pose.bones[bones['heel.02.L']] - pbone.rigify_type = '' + pbone = obj.pose.bones[bones['breast.L']] + pbone.rigify_type = 'basic.super_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' - pbone.bone.layers = [False, False, False, 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] - pbone = obj.pose.bones[bones['toe.R']] - pbone.rigify_type = '' + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['breast.R']] + pbone.rigify_type = 'basic.super_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' - pbone.bone.layers = [False, False, False, False, False, False, 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] - pbone = obj.pose.bones[bones['heel.02.R']] + pbone.rotation_mode = 'YXZ' + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['toe.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.bone.layers = [False, False, False, False, False, False, 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] - pbone = obj.pose.bones[bones['forearm.L']] + pbone.bone.layers = [False, False, False, False, 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] + pbone = obj.pose.bones[bones['heel.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.bone.layers = [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, False, False] - pbone = obj.pose.bones[bones['forearm.R']] + pbone.bone.layers = [False, False, False, False, 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] + pbone = obj.pose.bones[bones['toe.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.bone.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] - pbone = obj.pose.bones[bones['hand.L']] + pbone.bone.layers = [False, False, False, False, False, False, False, 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] + pbone = obj.pose.bones[bones['heel.02.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.bone.layers = [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, False, False] - pbone = obj.pose.bones[bones['hand.R']] + pbone.bone.layers = [False, False, False, False, False, False, False, 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] + 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.bone.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] - pbone = obj.pose.bones[bones['palm.01.L']] - pbone.rigify_type = 'palm' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, True) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.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] - pbone = obj.pose.bones[bones['palm.02.L']] - pbone.rigify_type = '' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, True) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.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] - pbone = obj.pose.bones[bones['palm.03.L']] - pbone.rigify_type = '' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, True) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.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] - pbone = obj.pose.bones[bones['palm.04.L']] - pbone.rigify_type = '' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, True, True) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'YXZ' - pbone.bone.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] - pbone = obj.pose.bones[bones['palm.01.R']] - 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' - pbone.bone.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] - pbone = obj.pose.bones[bones['palm.02.R']] - 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.bone.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] - pbone = obj.pose.bones[bones['palm.03.R']] - 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.bone.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] - pbone = obj.pose.bones[bones['palm.04.R']] - pbone.rigify_type = '' + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['upper_arm.L']] + pbone.rigify_type = 'limbs.super_limb' 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.bone.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] - pbone = obj.pose.bones[bones['f_index.01.L']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' - pbone.bone.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] + pbone.bone.layers = [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, False] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.separate_ik_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] + 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 - pbone = obj.pose.bones[bones['thumb.01.L']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.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] 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] + pbone.rigify_parameters.separate_hose_layers = True except AttributeError: pass try: - pbone.rigify_parameters.separate_extra_layers = True + 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 - pbone = obj.pose.bones[bones['f_middle.01.L']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.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] try: - pbone.rigify_parameters.separate_extra_layers = True + 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.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] + 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['f_ring.01.L']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) + pbone = obj.pose.bones[bones['upper_arm.R']] + pbone.rigify_type = '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' - pbone.bone.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] + pbone.bone.layers = [False, 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] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.separate_ik_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] + pbone.rigify_parameters.ik_layers = [False, False, 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] except AttributeError: pass - pbone = obj.pose.bones[bones['f_pinky.01.L']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.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] try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.separate_hose_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] + pbone.rigify_parameters.hose_layers = [False, False, False, 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] except AttributeError: pass - pbone = obj.pose.bones[bones['f_index.01.R']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) - pbone.lock_rotation = (False, False, False) - pbone.lock_rotation_w = False - pbone.lock_scale = (False, False, False) - pbone.rotation_mode = 'QUATERNION' - pbone.bone.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] 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] + pbone.rigify_parameters.tweak_layers = [False, False, False, 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] except AttributeError: pass try: - pbone.rigify_parameters.separate_extra_layers = True + pbone.rigify_parameters.fk_layers = [False, False, 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] except AttributeError: pass - pbone = obj.pose.bones[bones['thumb.01.R']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) + 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' - pbone.bone.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] - 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 - pbone = obj.pose.bones[bones['f_middle.01.R']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) + pbone.bone.layers = [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, False] + 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.bone.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] - 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 - pbone = obj.pose.bones[bones['f_ring.01.R']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['forearm.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.bone.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] - 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 - pbone = obj.pose.bones[bones['f_pinky.01.R']] - pbone.rigify_type = 'finger' - pbone.lock_location = (True, True, True) + pbone.bone.layers = [False, 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] + pbone = obj.pose.bones[bones['face']] + pbone.rigify_type = 'faces.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.bone.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] - try: - pbone.rigify_parameters.separate_extra_layers = True - except AttributeError: - pass + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] 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] + pbone.rigify_parameters.secondary_layers = [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, False, False] except AttributeError: pass - pbone = obj.pose.bones[bones['f_index.02.L']] + 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' - pbone.bone.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] - pbone = obj.pose.bones[bones['thumb.02.L']] + pbone.bone.layers = [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, False] + pbone = obj.pose.bones[bones['hand.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.bone.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] - pbone = obj.pose.bones[bones['f_middle.02.L']] + pbone.bone.layers = [False, 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] + 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.bone.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] - pbone = obj.pose.bones[bones['f_ring.02.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_pinky.02.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_index.02.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['thumb.02.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_middle.02.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_ring.02.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_pinky.02.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_index.03.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['thumb.03.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_middle.03.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_ring.03.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_pinky.03.L']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_index.03.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['thumb.03.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_middle.03.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_ring.03.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] - pbone = obj.pose.bones[bones['f_pinky.03.R']] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.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] + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['palm.01.L']] + pbone.rigify_type = 'limbs.super_palm' + 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.bone.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] + pbone = obj.pose.bones[bones['palm.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 = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.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 = 'YXZ' + pbone.bone.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] + 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.bone.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] + pbone = obj.pose.bones[bones['palm.01.R']] + pbone.rigify_type = 'limbs.super_palm' + 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.bone.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] + pbone = obj.pose.bones[bones['palm.02.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 = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.03.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 = 'YXZ' + pbone.bone.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] + pbone = obj.pose.bones[bones['palm.04.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 = 'YXZ' + pbone.bone.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] + 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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.01.L']] + pbone.rigify_type = 'limbs.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.bone.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] + 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['thumb.01.L']] + pbone.rigify_type = 'limbs.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.bone.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] + 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.separate_extra_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_extra_layers = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['f_middle.01.L']] + pbone.rigify_type = 'limbs.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.bone.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] + 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_ring.01.L']] + pbone.rigify_type = 'limbs.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.bone.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] + 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.01.L']] + pbone.rigify_type = 'limbs.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.bone.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] + 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_index.01.R']] + pbone.rigify_type = 'limbs.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.bone.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] + 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.separate_extra_layers = True + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_extra_layers = False + except AttributeError: + pass + pbone = obj.pose.bones[bones['thumb.01.R']] + pbone.rigify_type = 'limbs.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.bone.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] + 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_middle.01.R']] + pbone.rigify_type = 'limbs.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.bone.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] + 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_ring.01.R']] + pbone.rigify_type = 'limbs.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.bone.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] + 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.01.R']] + pbone.rigify_type = 'limbs.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.bone.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] + 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['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.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.bone.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] + pbone = obj.pose.bones[bones['thumb.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.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.bone.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] + 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.bone.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] + pbone = obj.pose.bones[bones['f_index.02.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.bone.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] + pbone = obj.pose.bones[bones['thumb.02.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.02.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.02.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.bone.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] + pbone = obj.pose.bones[bones['f_pinky.02.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.bone.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] + 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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['f_index.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['thumb.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_middle.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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_ring.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' + pbone.bone.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] + 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' + pbone.bone.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] + pbone = obj.pose.bones[bones['f_index.03.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.bone.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] + pbone = obj.pose.bones[bones['thumb.03.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.bone.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] + pbone = obj.pose.bones[bones['f_middle.03.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.bone.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] + pbone = obj.pose.bones[bones['f_ring.03.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.bone.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] + pbone = obj.pose.bones[bones['f_pinky.03.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.bone.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] + 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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['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' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] bpy.ops.object.mode_set(mode='EDIT') for bone in arm.edit_bones: @@ -1194,7 +2724,7 @@ def create(obj): bone.select_tail = True arm.edit_bones.active = bone - arm.layers = [(x in [0, 2, 4, 6, 9, 12, 15]) for x in range(32)] + arm.layers = [(x in [0, 3, 5, 7, 10, 13, 16]) for x in range(32)] if __name__ == "__main__": - create(bpy.context.active_object) + create(bpy.context.active_object) \ No newline at end of file diff --git a/rigify/rig_ui_template.py b/rigify/rig_ui_template.py index 717410da7b14ab789eda7aa4af13b5a426614bea..19952ee3f3d5a775e407a1d95493e642cb95d4ce 100644 --- a/rigify/rig_ui_template.py +++ b/rigify/rig_ui_template.py @@ -21,7 +21,7 @@ UI_SLIDERS = ''' import bpy from mathutils import Matrix, Vector -from math import acos, pi +from math import acos, pi, radians rig_id = "%s" @@ -59,6 +59,58 @@ def rotation_difference(mat1, mat2): angle = -angle + (2*pi) return angle +def tail_distance(angle,bone_ik,bone_fk): + """ Returns the distance between the tails of two bones + after rotating bone_ik in AXIS_ANGLE mode. + """ + rot_mod=bone_ik.rotation_mode + if rot_mod != 'AXIS_ANGLE': + bone_ik.rotation_mode = 'AXIS_ANGLE' + bone_ik.rotation_axis_angle[0] = angle + bpy.context.scene.update() + + dv = (bone_fk.tail - bone_ik.tail).length + + bone_ik.rotation_mode = rot_mod + return dv + +def find_min_range(bone_ik,bone_fk,f=tail_distance,delta=pi/8): + """ finds the range where lies the minimum of function f applied on bone_ik and bone_fk + at a certain angle. + """ + rot_mod=bone_ik.rotation_mode + if rot_mod != 'AXIS_ANGLE': + bone_ik.rotation_mode = 'AXIS_ANGLE' + + start_angle = bone_ik.rotation_axis_angle[0] + angle = start_angle + while (angle > (start_angle - 2*pi)) and (angle < (start_angle + 2*pi)): + l_dist = f(angle-delta,bone_ik,bone_fk) + c_dist = f(angle,bone_ik,bone_fk) + r_dist = f(angle+delta,bone_ik,bone_fk) + if min((l_dist,c_dist,r_dist)) == c_dist: + bone_ik.rotation_mode = rot_mod + return (angle-delta,angle+delta) + else: + angle=angle+delta + +def ternarySearch(f, left, right, bone_ik, bone_fk, absolutePrecision): + """ + Find minimum of unimodal function f() within [left, right] + To find the maximum, revert the if/else statement or revert the comparison. + """ + while True: + #left and right are the current bounds; the maximum is between them + if abs(right - left) < absolutePrecision: + return (left + right)/2 + + leftThird = left + (right - left)/3 + rightThird = right - (right - left)/3 + + if f(leftThird, bone_ik, bone_fk) > f(rightThird, bone_ik, bone_fk): + left = leftThird + else: + right = rightThird ######################################### ## "Visual Transform" helper functions ## @@ -103,7 +155,7 @@ def set_pose_translation(pose_bone, mat): """ Sets the pose bone's translation to the same translation as the given matrix. Matrix should be given in bone's local space. """ - if pose_bone.bone.use_local_location is True: + if pose_bone.bone.use_local_location == True: pose_bone.location = mat.to_translation() else: loc = mat.to_translation() @@ -174,6 +226,18 @@ def match_pose_scale(pose_bone, target_bone): bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='POSE') +def correct_rotation(bone_ik, bone_fk): + """ Corrects the ik rotation in ik2fk snapping functions + """ + + alfarange = find_min_range(bone_ik,bone_fk) + alfamin = ternarySearch(tail_distance,alfarange[0],alfarange[1],bone_ik,bone_fk,0.1) + + rot_mod = bone_ik.rotation_mode + if rot_mod != 'AXIS_ANGLE': + bone_ik.rotation_mode = 'AXIS_ANGLE' + bone_ik.rotation_axis_angle[0] = alfamin + bone_ik.rotation_mode = rot_mod ############################## ## IK/FK snapping functions ## @@ -245,24 +309,41 @@ def fk2ik_arm(obj, fk, ik): farmi = obj.pose.bones[ik[1]] handi = obj.pose.bones[ik[2]] - # Stretch - if handi['auto_stretch'] == 0.0: - uarm['stretch_length'] = handi['stretch_length'] - else: - diff = (uarmi.vector.length + farmi.vector.length) / (uarm.vector.length + farm.vector.length) - uarm['stretch_length'] *= diff + if 'auto_stretch' in handi.keys(): + # This is kept for compatibility with legacy rigify Human + # Stretch + if handi['auto_stretch'] == 0.0: + uarm['stretch_length'] = handi['stretch_length'] + else: + diff = (uarmi.vector.length + farmi.vector.length) / (uarm.vector.length + farm.vector.length) + uarm['stretch_length'] *= diff + + # Upper arm position + match_pose_rotation(uarm, uarmi) + match_pose_scale(uarm, uarmi) - # Upper arm position - match_pose_rotation(uarm, uarmi) - match_pose_scale(uarm, uarmi) + # Forearm position + match_pose_rotation(farm, farmi) + match_pose_scale(farm, farmi) - # Forearm position - match_pose_rotation(farm, farmi) - match_pose_scale(farm, farmi) + # Hand position + match_pose_rotation(hand, handi) + match_pose_scale(hand, handi) + else: + # Upper arm position + match_pose_translation(uarm, uarmi) + match_pose_rotation(uarm, uarmi) + match_pose_scale(uarm, uarmi) + + # Forearm position + #match_pose_translation(hand, handi) + match_pose_rotation(farm, farmi) + match_pose_scale(farm, farmi) - # Hand position - match_pose_rotation(hand, handi) - match_pose_scale(hand, handi) + # Hand position + match_pose_translation(hand, handi) + match_pose_rotation(hand, handi) + match_pose_scale(hand, handi) def ik2fk_arm(obj, fk, ik): @@ -277,19 +358,38 @@ def ik2fk_arm(obj, fk, ik): uarmi = obj.pose.bones[ik[0]] farmi = obj.pose.bones[ik[1]] handi = obj.pose.bones[ik[2]] - pole = obj.pose.bones[ik[3]] - # Stretch - handi['stretch_length'] = uarm['stretch_length'] + main_parent = obj.pose.bones[ik[4]] + + if ik[3] != "" and main_parent['pole_vector']: + pole = obj.pose.bones[ik[3]] + else: + pole = None + - # Hand position - match_pose_translation(handi, hand) - match_pose_rotation(handi, hand) - match_pose_scale(handi, hand) + if pole: + # Stretch + # handi['stretch_length'] = uarm['stretch_length'] - # Pole target position - match_pole_target(uarmi, farmi, pole, uarm, (uarmi.length + farmi.length)) + # Hand position + match_pose_translation(handi, hand) + match_pose_rotation(handi, hand) + match_pose_scale(handi, hand) + # Pole target position + match_pole_target(uarmi, farmi, pole, uarm, (uarmi.length + farmi.length)) + else: + # Hand position + match_pose_translation(handi, hand) + match_pose_rotation(handi, hand) + match_pose_scale(handi, hand) + + # Upper Arm position + match_pose_translation(uarmi, uarm) + match_pose_rotation(uarmi, uarm) + match_pose_scale(uarmi, uarm) + # Rotation Correction + correct_rotation(uarmi, uarm) def fk2ik_leg(obj, fk, ik): """ Matches the fk bones in a leg rig to the ik bones. @@ -306,28 +406,48 @@ def fk2ik_leg(obj, fk, ik): footi = obj.pose.bones[ik[2]] mfooti = obj.pose.bones[ik[3]] - # Stretch - if footi['auto_stretch'] == 0.0: - thigh['stretch_length'] = footi['stretch_length'] + if 'auto_stretch' in footi.keys(): + # This is kept for compatibility with legacy rigify Human + # Stretch + if footi['auto_stretch'] == 0.0: + thigh['stretch_length'] = footi['stretch_length'] + else: + diff = (thighi.vector.length + shini.vector.length) / (thigh.vector.length + shin.vector.length) + thigh['stretch_length'] *= diff + + # Thigh position + match_pose_rotation(thigh, thighi) + match_pose_scale(thigh, thighi) + + # Shin position + match_pose_rotation(shin, shini) + match_pose_scale(shin, shini) + + # Foot position + mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local + footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat + set_pose_rotation(foot, footmat) + set_pose_scale(foot, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + else: - diff = (thighi.vector.length + shini.vector.length) / (thigh.vector.length + shin.vector.length) - thigh['stretch_length'] *= diff - - # Thigh position - match_pose_rotation(thigh, thighi) - match_pose_scale(thigh, thighi) - - # Shin position - match_pose_rotation(shin, shini) - match_pose_scale(shin, shini) - - # Foot position - mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local - footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat - set_pose_rotation(foot, footmat) - set_pose_scale(foot, footmat) - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='POSE') + # Thigh position + match_pose_translation(thigh, thighi) + match_pose_rotation(thigh, thighi) + match_pose_scale(thigh, thighi) + + # Shin position + match_pose_rotation(shin, shini) + match_pose_scale(shin, shini) + + # Foot position + mat = mfoot.bone.matrix_local.inverted() * foot.bone.matrix_local + footmat = get_pose_matrix_in_other_space(mfooti.matrix, foot) * mat + set_pose_rotation(foot, footmat) + set_pose_scale(foot, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') def ik2fk_leg(obj, fk, ik): @@ -339,30 +459,65 @@ def ik2fk_leg(obj, fk, ik): thigh = obj.pose.bones[fk[0]] shin = obj.pose.bones[fk[1]] mfoot = obj.pose.bones[fk[2]] + if fk[3] != "": + foot = obj.pose.bones[fk[3]] + else: + foot = None thighi = obj.pose.bones[ik[0]] shini = obj.pose.bones[ik[1]] footi = obj.pose.bones[ik[2]] footroll = obj.pose.bones[ik[3]] - pole = obj.pose.bones[ik[4]] + + main_parent = obj.pose.bones[ik[6]] + + if ik[4] != "" and main_parent['pole_vector']: + pole = obj.pose.bones[ik[4]] + else: + pole = None mfooti = obj.pose.bones[ik[5]] - # Stretch - footi['stretch_length'] = thigh['stretch_length'] + if (not pole) and (foot): - # Clear footroll - set_pose_rotation(footroll, Matrix()) + # Clear footroll + set_pose_rotation(footroll, Matrix()) - # Foot position - mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local - footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) * mat - set_pose_translation(footi, footmat) - set_pose_rotation(footi, footmat) - set_pose_scale(footi, footmat) - bpy.ops.object.mode_set(mode='OBJECT') - bpy.ops.object.mode_set(mode='POSE') + # Foot position + mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local + footmat = get_pose_matrix_in_other_space(foot.matrix, footi) * mat + set_pose_translation(footi, footmat) + set_pose_rotation(footi, footmat) + set_pose_scale(footi, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') + + # Thigh position + match_pose_translation(thighi, thigh) + match_pose_rotation(thighi, thigh) + match_pose_scale(thighi, thigh) + + # Rotation Correction + correct_rotation(thighi,thigh) + + else: + # Stretch + if 'stretch_lenght' in footi.keys() and 'stretch_lenght' in thigh.keys(): + # Kept for compat with legacy rigify Human + footi['stretch_length'] = thigh['stretch_length'] + + # Clear footroll + set_pose_rotation(footroll, Matrix()) + + # Foot position + mat = mfooti.bone.matrix_local.inverted() * footi.bone.matrix_local + footmat = get_pose_matrix_in_other_space(mfoot.matrix, footi) * mat + set_pose_translation(footi, footmat) + set_pose_rotation(footi, footmat) + set_pose_scale(footi, footmat) + bpy.ops.object.mode_set(mode='OBJECT') + bpy.ops.object.mode_set(mode='POSE') - # Pole target position - match_pole_target(thighi, shini, pole, thigh, (thighi.length + shini.length)) + # Pole target position + match_pole_target(thighi, shini, pole, thigh, (thighi.length + shini.length)) ############################## @@ -386,7 +541,7 @@ class Rigify_Arm_FK2IK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo @@ -414,15 +569,17 @@ class Rigify_Arm_IK2FK(bpy.types.Operator): hand_ik = bpy.props.StringProperty(name="Hand IK Name") pole = bpy.props.StringProperty(name="Pole IK Name") + main_parent = bpy.props.StringProperty(name="Main Parent", default="") + @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo context.user_preferences.edit.use_global_undo = False try: - ik2fk_arm(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik, self.pole]) + ik2fk_arm(context.active_object, fk=[self.uarm_fk, self.farm_fk, self.hand_fk], ik=[self.uarm_ik, self.farm_ik, self.hand_ik, self.pole, self.main_parent]) finally: context.user_preferences.edit.use_global_undo = use_global_undo return {'FINISHED'} @@ -447,7 +604,7 @@ class Rigify_Leg_FK2IK(bpy.types.Operator): @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo @@ -469,7 +626,7 @@ class Rigify_Leg_IK2FK(bpy.types.Operator): thigh_fk = bpy.props.StringProperty(name="Thigh FK Name") shin_fk = bpy.props.StringProperty(name="Shin FK Name") mfoot_fk = bpy.props.StringProperty(name="MFoot FK Name") - + foot_fk = bpy.props.StringProperty(name="Foot FK Name", default="") thigh_ik = bpy.props.StringProperty(name="Thigh IK Name") shin_ik = bpy.props.StringProperty(name="Shin IK Name") foot_ik = bpy.props.StringProperty(name="Foot IK Name") @@ -477,15 +634,17 @@ class Rigify_Leg_IK2FK(bpy.types.Operator): pole = bpy.props.StringProperty(name="Pole IK Name") mfoot_ik = bpy.props.StringProperty(name="MFoot IK Name") + main_parent = bpy.props.StringProperty(name="Main Parent", default="") + @classmethod def poll(cls, context): - return (context.active_object is not None and context.mode == 'POSE') + return (context.active_object != None and context.mode == 'POSE') def execute(self, context): use_global_undo = context.user_preferences.edit.use_global_undo context.user_preferences.edit.use_global_undo = False try: - ik2fk_leg(context.active_object, fk=[self.thigh_fk, self.shin_fk, self.mfoot_fk], ik=[self.thigh_ik, self.shin_ik, self.foot_ik, self.footroll, self.pole, self.mfoot_ik]) + ik2fk_leg(context.active_object, fk=[self.thigh_fk, self.shin_fk, self.mfoot_fk, self.foot_fk], ik=[self.thigh_ik, self.shin_ik, self.foot_ik, self.footroll, self.pole, self.mfoot_ik, self.main_parent]) finally: context.user_preferences.edit.use_global_undo = use_global_undo return {'FINISHED'} diff --git a/rigify/rigs/basic/super_copy.py b/rigify/rigs/basic/super_copy.py new file mode 100644 index 0000000000000000000000000000000000000000..cd0f144fa62b7dd2ccac5f84171b3d095af08d32 --- /dev/null +++ b/rigify/rigs/basic/super_copy.py @@ -0,0 +1,161 @@ +#====================== 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 ======================== + +# <pep8 compliant> + +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) + + +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.enabled = params.make_control + 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.super_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/rigs/experimental/__init__.py b/rigify/rigs/experimental/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py new file mode 100644 index 0000000000000000000000000000000000000000..cff25f2a0c4cb351d321663d22f7e896aa7f2768 --- /dev/null +++ b/rigify/rigs/experimental/super_chain.py @@ -0,0 +1,1414 @@ +import bpy +from mathutils import Vector +from math import pi +from ...utils import copy_bone, flip_bone, put_bone, org, align_bone_y_axis, align_bone_x_axis, align_bone_z_axis +from ...utils import strip_org, make_deformer_name, connected_children_names +from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_chain_widget +from ...utils import MetarigError, make_mechanism_name, create_cube_widget +from rna_prop_ui import rna_idprop_ui_prop_get +from ..limbs.limb_utils import get_bone_name + +script = """ +controls = [%s] +torso = '%s' + +if is_selected( controls ): + layout.prop( pose_bones[ torso ], '["%s"]', slider = True ) + layout.prop( pose_bones[ torso ], '["%s"]', slider = True ) +""" + + +class Rig: + + def __init__(self, obj, bone_name, params): + """ A simplified version of the torso rig. Basically a connected-DEF chain of bones """ + + eb = obj.data.edit_bones + + self.obj = obj + self.org_bones = [bone_name] + connected_children_names(obj, bone_name) + self.params = params + self.spine_length = sum([eb[b].length for b in self.org_bones]) + self.bbones = params.bbones + + # Check if user provided the positions of the neck and pivot + # if params.neck_pos and params.pivot_pos: + # self.neck_pos = params.neck_pos + # self.pivot_pos = params.pivot_pos + # else: + # raise MetarigError( + # "RIGIFY ERROR: please specify neck and pivot bone positions" + # ) + # + # # Check if neck is lower than pivot + # if params.neck_pos <= params.pivot_pos: + # raise MetarigError( + # "RIGIFY ERROR: Neck cannot be below or the same as pivot" + # ) + + # if params.control_num: + # self.control_num = params.control_num + # else: + # raise MetarigError( + # "RIGIFY ERROR: please specify number of controls" + # ) + # + # if params.control_num > round(len(eb)/2): + # raise MetarigError( + # "RIGIFY ERROR: Number of controls must be <= number of bones/2" + # ) + + # TODO: + # Limit neck_pos prop to 1 --> num of bones - 1 (last is head) + # Limit pivot_pos prop to 2 --> num of bones (must leave place for lower torso) + + # if params.tail_pos: + # self.tail_pos = params.tail_pos + + # Assign values to tweak layers props if opted by user + if params.tweak_extra_layers: + self.tweak_layers = list(params.tweak_layers) + else: + self.tweak_layers = None + + # Report error of user created less than the minimum of 4 bones for rig + # if len(self.org_bones) <= 4: + # raise MetarigError( + # "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name)) + # ) + + + # def build_bone_structure( self ): + # """ Divide meta-rig into lists of bones according to torso rig anatomy: + # Neck --> Upper torso --> Lower torso --> Tail (optional) """ + # + # if self.pivot_pos and self.neck_pos: + # + # neck_index = self.neck_pos - 1 + # pivot_index = self.pivot_pos - 1 + # + # tail_index = 0 + # if 'tail_pos' in dir(self): + # tail_index = self.tail_pos - 1 + # + # neck_bones = self.org_bones[neck_index::] + # upper_torso_bones = self.org_bones[pivot_index:neck_index] + # lower_torso_bones = self.org_bones[tail_index:pivot_index] + # + # tail_bones = [] + # if tail_index: + # tail_bones = self.org_bones[::tail_index+1] + # + # return { + # 'neck' : neck_bones, + # 'upper' : upper_torso_bones, + # 'lower' : lower_torso_bones, + # 'tail' : tail_bones + # } + # + # else: + # return 'ERROR' + + def orient_bone( self, eb, axis, scale, reverse = False ): + v = Vector((0,0,0)) + + setattr(v,axis,scale) + + if reverse: + tail_vec = v * self.obj.matrix_world + eb.head[:] = eb.tail + eb.tail[:] = eb.head + tail_vec + else: + tail_vec = v * self.obj.matrix_world + eb.tail[:] = eb.head + tail_vec + + def create_pivot(self, bones=None, pivot=None): + """ Create the pivot control and mechanism bones """ + + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones + + if not pivot: + pivot = int(len(org_bones)/2) + + pivot_name = org_bones[pivot] + if '.L' in pivot_name: + prefix = strip_org(org_bones[pivot]).split('.')[0] + '.L' + elif '.R' in pivot_name: + prefix = strip_org(org_bones[pivot]).split('.')[0] + '.R' + else: + prefix = strip_org(org_bones[pivot]).split('.')[0] + + ctrl_name = get_bone_name(prefix, 'ctrl', 'pivot') + ctrl_name = copy_bone(self.obj, pivot_name, ctrl_name) + ctrl_eb = eb[ ctrl_name ] + + self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 ) + + pivot_loc = eb[pivot_name].head + ((eb[pivot_name].tail - eb[pivot_name].head)/2)*(len(org_bones)%2) + + put_bone( self.obj, ctrl_name, pivot_loc) + + v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last + v.normalize() + v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v + v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain + + if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03: #if v_point is too small it's not usable + v_point = eb[org_bones[0]].x_axis + + if self.params.tweak_axis == 'auto': + align_bone_y_axis(self.obj, ctrl_name, v) + align_bone_z_axis(self.obj, ctrl_name, -v_point) + elif self.params.tweak_axis == 'x': + align_bone_y_axis(self.obj, ctrl_name, Vector((1,0,0))) + align_bone_x_axis(self.obj, ctrl_name, Vector((0,0,1))) + elif self.params.tweak_axis == 'y': + align_bone_y_axis(self.obj, ctrl_name, Vector((0,1,0))) + align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0))) + elif self.params.tweak_axis == 'z': + align_bone_y_axis(self.obj, ctrl_name, Vector((0,0,1))) + align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0))) + + return { + 'ctrl' : ctrl_name + }#Todo modify following + + + org_bones = self.org_bones + pivot_name = org_bones[pivot-1] + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Create torso control bone + torso_name = 'torso' + ctrl_name = copy_bone(self.obj, pivot_name, torso_name) + ctrl_eb = eb[ctrl_name] + + self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 ) + + # Create mch_pivot + mch_name = make_mechanism_name( 'pivot' ) + mch_name = copy_bone(self.obj, ctrl_name, mch_name) + mch_eb = eb[mch_name] + + mch_eb.length /= 4 + + # Positioning pivot in a more usable location for animators + if hasattr(self, 'tail_pos') and self.tail_pos > 0: + pivot_loc = eb[org_bones[pivot-1]].head + else: + pivot_loc = (eb[org_bones[0]].head + eb[org_bones[0]].tail) / 2 + + put_bone(self.obj, ctrl_name, pivot_loc) + + return { + 'ctrl': ctrl_name, + 'mch': mch_name + } + + def create_deform(self): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones + + def_bones = [] + for o in org_bones: + def_name = make_deformer_name(strip_org(o)) + def_name = copy_bone(self.obj, o, def_name) + def_bones.append(def_name) + + bpy.ops.object.mode_set(mode='POSE') + # Create bbone segments + for bone in def_bones: + self.obj.data.bones[bone].bbone_segments = self.bbones + + if not self.SINGLE_BONE: + self.obj.data.bones[def_bones[0]].bbone_in = 0.0 + self.obj.data.bones[def_bones[-1]].bbone_out = 0.0 + else: + self.obj.data.bones[def_bones[0]].bbone_in = 1.0 + self.obj.data.bones[def_bones[-1]].bbone_out = 1.0 + bpy.ops.object.mode_set(mode='EDIT') + + return def_bones + + def create_neck( self, neck_bones ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Create neck control + neck = copy_bone( self.obj, org(neck_bones[0]), 'neck' ) + neck_eb = eb[ neck ] + + # Neck spans all neck bones (except head) + neck_eb.tail[:] = eb[ org(neck_bones[-1]) ].head + + # Create head control + head = copy_bone( self.obj, org(neck_bones[-1]), 'head' ) + + # MCH bones + # Neck MCH stretch + mch_str = copy_bone( self.obj, neck, make_mechanism_name('STR-neck') ) + + # Neck MCH rotation + mch_neck = copy_bone( + self.obj, neck, make_mechanism_name('ROT-neck') + ) + + self.orient_bone( eb[mch_neck], 'y', self.spine_length / 10 ) + + # Head MCH rotation + mch_head = copy_bone( + self.obj, head, make_mechanism_name('ROT-head') + ) + + self.orient_bone( eb[mch_head], 'y', self.spine_length / 10 ) + + twk,mch = [],[] + + # Intermediary bones + for b in neck_bones[1:-1]: # All except 1st neck and (last) head + mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) ) + eb[mch_name].length /= 4 + + mch += [ mch_name ] + + # Tweak bones + for b in neck_bones[:-1]: # All except last bone + twk_name = "tweak_" + b + twk_name = copy_bone( self.obj, org(b), twk_name ) + + eb[twk_name].length /= 2 + + twk += [ twk_name ] + + return { + 'ctrl_neck' : neck, + 'ctrl' : head, + 'mch_str' : mch_str, + 'mch_neck' : mch_neck, + 'mch_head' : mch_head, + 'mch' : mch, + 'tweak' : twk + } + + def create_chest( self, chest_bones ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # get total spine length + + # Create chest control bone + chest = copy_bone( self.obj, org( chest_bones[0] ), 'chest' ) + self.orient_bone( eb[chest], 'y', self.spine_length / 3 ) + + # create chest mch_wgt + mch_wgt = copy_bone( + self.obj, org( chest_bones[-1] ), + make_mechanism_name( 'WGT-chest' ) + ) + + # Create mch and twk bones + twk,mch = [],[] + + for b in chest_bones: + mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) ) + self.orient_bone( eb[mch_name], 'y', self.spine_length / 10 ) + + twk_name = "tweak_" + b + twk_name = copy_bone( self.obj, org(b), twk_name ) + eb[twk_name].length /= 2 + + mch += [ mch_name ] + twk += [ twk_name ] + + return { + 'ctrl' : chest, + 'mch' : mch, + 'tweak' : twk, + 'mch_wgt' : mch_wgt + } + + def create_hips( self, hip_bones ): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Create hips control bone + hips = copy_bone( self.obj, org( hip_bones[-1] ), 'hips' ) + self.orient_bone( + eb[hips], + 'y', + self.spine_length / 4, + reverse = True + ) + + # create hips mch_wgt + mch_wgt = copy_bone( + self.obj, org( hip_bones[0] ), + make_mechanism_name( 'WGT-hips' ) + ) + + # Create mch and tweak bones + twk,mch = [],[] + for b in hip_bones: + mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) ) + self.orient_bone( + eb[mch_name], 'y', self.spine_length / 10, reverse = True + ) + + twk_name = "tweak_" + b + twk_name = copy_bone( self.obj, org( b ), twk_name ) + + eb[twk_name].length /= 2 + + mch += [ mch_name ] + twk += [ twk_name ] + + return { + 'ctrl' : hips, + 'mch' : mch, + 'tweak' : twk, + 'mch_wgt' : mch_wgt + } + + def create_tail( self, tail_bones ): + pass + + def create_chain(self): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones + + twk, mch, mch_ctrl, ctrl = [], [], [], [] + + suffix = '' + if '.L' in org_bones[0]: + suffix = '.L' + elif '.R' in org_bones[0]: + suffix = '.R' + + mch_auto = '' + if not self.SINGLE_BONE: + mch_name = copy_bone( self.obj, org(org_bones[0]), 'MCH-AUTO-'+strip_org(org_bones[0]).split('.')[0] + suffix) + eb[mch_name].head = eb[org_bones[0]].head + eb[mch_name].tail = eb[org_bones[-1]].tail + + mch_auto = mch_name + + # Intermediary bones + for b in org_bones: # All + + if self.SINGLE_BONE: + mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b))) + eb[mch_name].length /= 4 + put_bone(self.obj, mch_name, eb[b].head - (eb[mch_name].tail - eb[mch_name].head)) + align_bone_z_axis(self.obj, mch_name, eb[b].z_axis) + if '.' in mch_name: + mch_rev_name = mch_name.split('.')[0] + '_reverse.' + mch_name.split('.')[1] + else: + mch_rev_name = mch_name + '_reverse' + mch_rev_name = copy_bone(self.obj, org(b), mch_rev_name) + eb[mch_rev_name].length /= 4 + eb[mch_rev_name].tail = eb[mch_name].head + align_bone_z_axis(self.obj, mch_rev_name, eb[b].z_axis) + mch += [mch_name] + mch += [mch_rev_name] + break + + mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b))) + eb[mch_name].length /= 4 + + mch += [ mch_name ] + + if b == org_bones[-1]: #Add extra + mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b))) + eb[mch_name].length /= 4 + put_bone(self.obj, mch_name, eb[b].tail) + mch += [ mch_name ] + + # Tweak & Ctrl bones + v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last + v.normalize() + v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v + v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain + + if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03: + v_point = eb[org_bones[0]].x_axis + + for b in org_bones: # All + + suffix = '' + if '.L' in b: + suffix = '.L' + elif '.R' in b: + suffix = '.R' + + if b == org_bones[0]: + name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') + name = copy_bone(self.obj, org(b), name) + align_bone_x_axis(self.obj, name, eb[org(b)].x_axis) + ctrl += [name] + else: + name = get_bone_name(b, 'ctrl', 'tweak') + name = copy_bone(self.obj, org(b), name) + twk += [name] + + self.orient_bone(eb[name], 'y', eb[name].length / 2) + + if self.params.tweak_axis == 'auto': + align_bone_y_axis(self.obj, name, v) + align_bone_z_axis(self.obj, name, -v_point) # invert? + elif self.params.tweak_axis == 'x': + align_bone_y_axis(self.obj, name, Vector((1,0,0))) + align_bone_x_axis(self.obj, name, Vector((0,0,1))) + elif self.params.tweak_axis == 'y': + align_bone_y_axis(self.obj, name, Vector((0,1,0))) + align_bone_x_axis(self.obj, name, Vector((1,0,0))) + elif self.params.tweak_axis == 'z': + align_bone_y_axis(self.obj, name, Vector((0,0,1))) + align_bone_x_axis(self.obj, name, Vector((1,0,0))) + + if b == org_bones[-1]: # Add extra + ctrl_name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') + ctrl_name = copy_bone(self.obj, org(b), ctrl_name) + + self.orient_bone(eb[ctrl_name], 'y', eb[ctrl_name].length / 2) + + #TODO check this if else + if self.params.conv_bone: + align_bone_y_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].y_axis) + align_bone_x_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].x_axis) + align_bone_z_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].z_axis) + + else: + if twk: + lastname = twk[-1] + else: + lastname = ctrl[-1] + align_bone_y_axis(self.obj, ctrl_name, eb[lastname].y_axis) + align_bone_x_axis(self.obj, ctrl_name, eb[lastname].x_axis) + put_bone(self.obj, ctrl_name, eb[b].tail) + + ctrl += [ctrl_name] + + conv_twk = '' + # Convergence tweak + if self.params.conv_bone: + conv_twk = get_bone_name(self.params.conv_bone, 'ctrl', 'tweak') #"tweak_" + self.params.conv_bone + + if not(conv_twk in eb.keys()): + conv_twk = copy_bone( self.obj, org(self.params.conv_bone), conv_twk ) + + # Mch controls + suffix = '' + if '.L' in b: + suffix = '.L' + elif '.R' in b: + suffix = '.R' + + for b in org_bones: + mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix + mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name ) + + self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 ) + + if b == org_bones[0] or b == org_bones[-1]: + name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b) + else: + name = get_bone_name(b, 'ctrl', 'tweak') #"tweak_" + strip_org(b) + # align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis) + # align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis) + + align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis) + align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis) + + if self.SINGLE_BONE: + align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis) + + mch_ctrl += [mch_ctrl_name] + + if b == org_bones[-1]: #Add extra + mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix + mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name ) + + self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 ) + + name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b) + #align_bone_y_axis(self.obj, mch_ctrl_name, -eb[name].z_axis) + align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis) + align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis) + + put_bone(self.obj, mch_ctrl_name, eb[b].tail) + + if self.SINGLE_BONE: + align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis) + + mch_ctrl += [mch_ctrl_name] + + return { + 'mch' : mch, + 'mch_ctrl' : mch_ctrl, + 'mch_auto' : mch_auto, + 'tweak' : twk, + 'ctrl' : ctrl, + 'conv' : conv_twk + } + + def parent_bones(self, bones): + org_bones = self.org_bones + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + # Parent deform bones + for i, b in enumerate(bones['def']): + if i > 0: # For all bones but the first (which has no parent) + eb[b].parent = eb[bones['def'][i-1]] # to previous + eb[b].use_connect = True + + # Todo check case when sup_chain is in bigger rig + eb[bones['def'][0]].parent = eb[bones['chain']['mch'][0]] + + for i, twk in enumerate(bones['chain']['tweak']): + eb[ twk ].parent = eb[bones['chain']['mch_ctrl'][i+1]] + eb[ twk ].use_inherit_scale = False + + eb[bones['chain']['ctrl'][0]].parent = eb[bones['chain']['mch_ctrl'][0]] + eb[bones['chain']['ctrl'][0]].use_inherit_scale = False + eb[bones['chain']['ctrl'][1]].parent = eb[bones['chain']['mch_ctrl'][-1]] + eb[bones['chain']['ctrl'][1]].use_inherit_scale = False + + + if 'pivot' in bones.keys(): + eb[ bones['pivot']['ctrl'] ].use_inherit_scale = False + + for i,mch in enumerate( bones['chain']['mch'] ): + if mch == bones['chain']['mch'][0]: + eb[ mch ].parent = eb[ bones['chain']['ctrl'][0] ] + elif mch == bones['chain']['mch'][-1]: + eb[ mch ].parent = eb[ bones['chain']['ctrl'][1] ] + else: + eb[ mch ].parent = eb[ bones['chain']['tweak'][i-1] ] + + if 'parent' in bones.keys(): + eb[bones['chain']['mch_auto']].parent = eb[bones['parent']] + eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['parent']] + eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['parent']] + + for i, mch_ctrl in enumerate( bones['chain']['mch_ctrl'][1:-1] ): + eb[ mch_ctrl ].parent = eb[ bones['chain']['mch_auto'] ] + + if 'pivot' in bones.keys(): + eb[ bones['pivot']['ctrl'] ].parent = eb[ bones['chain']['mch_auto'] ] + + if bones['chain']['conv']: + eb[ bones['chain']['tweak'][-1] ].parent = eb[ bones['chain']['conv'] ] + + if self.SINGLE_BONE: + eb[bones['chain']['ctrl'][0]].parent = None + eb[bones['chain']['ctrl'][-1]].parent = None + eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['chain']['ctrl'][0]] + eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['chain']['ctrl'][-1]] + eb[bones['chain']['mch'][0]].parent = eb[bones['chain']['mch'][1]] + eb[bones['chain']['mch'][1]].parent = eb[bones['chain']['mch_ctrl'][0]] + + return #TODO modify what follows + + # Parent control bones + # Head control => MCH-rotation_head + eb[ bones['neck']['ctrl'] ].parent = eb[ bones['neck']['mch_head'] ] + + # MCH stretch => neck ctrl + eb[ bones['neck']['mch_str'] ].parent = eb[ bones['neck']['ctrl_neck'] ] + + # Neck control => MCH-rotation_neck + eb[ bones['neck']['ctrl_neck'] ].parent = eb[ bones['neck']['mch_neck'] ] + + # Parent hips and chest controls to torso + eb[ bones['chest']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ] + eb[ bones['hips']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ] + + # Parent mch bones + # Neck mch + eb[ bones['neck']['mch_head'] ].parent = eb[ bones['neck']['ctrl_neck'] ] + + parent = eb[ bones['neck']['mch_str'] ] + for i,b in enumerate([ eb[n] for n in bones['neck']['mch'] ]): + b.parent = parent + + # Chest mch bones and neck mch + chest_mch = bones['chest']['mch'] + [ bones['neck']['mch_neck'] ] + for i,b in enumerate(chest_mch): + if i == 0: + eb[b].parent = eb[ bones['pivot']['ctrl'] ] + else: + eb[b].parent = eb[ chest_mch[i-1] ] + + # Hips mch bones + for i,b in enumerate( bones['hips']['mch'] ): + if i == len(bones['hips']['mch']) - 1: + eb[b].parent = eb[ bones['pivot']['ctrl'] ] + else: + eb[b].parent = eb[ bones['hips']['mch'][i+1] ] + + # mch pivot + eb[ bones['pivot']['mch'] ].parent = eb[ bones['chest']['mch'][0] ] + + # MCH widgets + eb[ bones['chest']['mch_wgt'] ].parent = eb[ bones['chest']['mch'][-1] ] + eb[ bones['hips' ]['mch_wgt'] ].parent = eb[ bones['hips' ]['mch'][0 ] ] + + # Tweaks + + # Neck tweaks + for i,twk in enumerate( bones['neck']['tweak'] ): + if i == 0: + eb[ twk ].parent = eb[ bones['neck']['ctrl_neck'] ] + else: + eb[ twk ].parent = eb[ bones['neck']['mch'][i-1] ] + + # Chest tweaks + for twk,mch in zip( bones['chest']['tweak'], bones['chest']['mch'] ): + if bones['chest']['tweak'].index( twk ) == 0: + eb[ twk ].parent = eb[ bones['pivot']['mch'] ] + else: + eb[ twk ].parent = eb[ mch ] + + # Hips tweaks + for i,twk in enumerate(bones['hips']['tweak']): + if i == 0: + eb[twk].parent = eb[ bones['hips']['mch'][i] ] + else: + eb[twk].parent = eb[ bones['hips']['mch'][i-1] ] + + # Parent orgs to matching tweaks + tweaks = bones['hips']['tweak'] + bones['chest']['tweak'] + tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ] + + if 'tail' in bones.keys(): + tweaks += bones['tail']['tweak'] + + for org, twk in zip( org_bones, tweaks ): + eb[ org ].parent = eb[ twk ] + + def make_constraint(self, bone, constraint): + bpy.ops.object.mode_set(mode='OBJECT') + pb = self.obj.pose.bones + + owner_pb = pb[bone] + const = owner_pb.constraints.new(constraint['constraint']) + const.target = self.obj + + # filter contraint props to those that actually exist in the current + # type of constraint, then assign values to each + for p in [k for k in constraint.keys() if k in dir(const)]: + setattr(const, p, constraint[p]) + + def constrain_bones(self, bones): + # DEF bones + + deform = bones['def'] + mch = bones['chain']['mch'] + mch_ctrl = bones['chain']['mch_ctrl'] + ctrls = bones['chain']['ctrl'] + tweaks = [ ctrls[0]] + bones['chain']['tweak'] + [ ctrls[-1] ] + + # if 'conv' in bones['chain'].keys(): + # conv_tweak = bones['chain']['conv'] + + for i, d in enumerate(deform): + + if len(deform) > 1: + self.make_constraint(d, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': mch[i], + 'owner_space': 'POSE', + 'target_space': 'POSE' + }) + + self.make_constraint(d, { + 'constraint': 'STRETCH_TO', + 'subtarget': tweaks[i+1] + }) + + if 'pivot' in bones.keys(): + step = 2/(len(self.org_bones)) + for i,b in enumerate(mch_ctrl): + xval = i*step + influence = 2*xval - xval**2 #parabolic influence of pivot + if (i != 0) and (i != len(mch_ctrl)-1): + self.make_constraint( b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : bones['pivot']['ctrl'], + 'influence' : influence, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + } ) + + # MCH-AUTO + + mch_auto = bones['chain']['mch_auto'] + + if mch_auto: + self.make_constraint( mch_auto, { + 'constraint': 'COPY_LOCATION', + 'subtarget' : mch[0], + 'owner_space' : 'WORLD', + 'target_space' : 'WORLD' + } ) + + self.make_constraint( mch_auto, { + 'constraint' : 'STRETCH_TO', + 'subtarget' : tweaks[-1] + } ) + + # PIVOT CTRL + + if 'pivot' in bones.keys(): + + pivot = bones['pivot']['ctrl'] + + self.make_constraint( pivot, { + 'constraint': 'COPY_ROTATION', + 'subtarget' : tweaks[0], + 'influence' : 0.33, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + } ) + + self.make_constraint( pivot, { + 'constraint': 'COPY_ROTATION', + 'subtarget' : tweaks[-1], + 'influence' : 0.33, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + } ) + + # MCH-CTRL + + # for i, b in enumerate(mch_ctrl): + # + # if i != 0 and mch_ctrl[i] != mch_ctrl[-1]: + # self.make_constraint( b, { + # 'constraint' : 'COPY_TRANSFORMS', + # 'subtarget' : tweaks[i-1], + # 'influence' : 0.5, + # 'owner_space' : 'LOCAL', + # 'target_space' : 'LOCAL' + # } ) + # + # self.make_constraint( b, { + # 'constraint' : 'COPY_TRANSFORMS', + # 'subtarget' : tweaks[i+1], + # 'influence' : 0.5, + # 'owner_space' : 'LOCAL', + # 'target_space' : 'LOCAL' + # } ) + + return #Todo mdify what follows + + # head and neck MCH bones + for b in [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]: + self.make_constraint( b, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : bones['pivot']['ctrl'], + } ) + self.make_constraint( b, { + 'constraint' : 'COPY_SCALE', + 'subtarget' : bones['pivot']['ctrl'], + } ) + + # Neck MCH Stretch + self.make_constraint( bones['neck']['mch_str'], { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : bones['neck']['ctrl'], + }) + + self.make_constraint( bones['neck']['mch_str'], { + 'constraint' : 'STRETCH_TO', + 'subtarget' : bones['neck']['ctrl'], + }) + + # Intermediary mch bones + intermediaries = [ bones['neck'], bones['chest'], bones['hips'] ] + + if 'tail' in bones.keys(): + intermediaries += bones['tail'] + + for i,l in enumerate(intermediaries): + mch = l['mch'] + factor = float( 1 / len( l['tweak'] ) ) + + for j,b in enumerate(mch): + if i == 0: + nfactor = float( (j + 1) / len( mch ) ) + self.make_constraint( b, { + 'constraint' : 'COPY_ROTATION', + 'subtarget' : l['ctrl'], + 'influence' : nfactor + } ) + else: + self.make_constraint( b, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : l['ctrl'], + 'influence' : factor, + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + } ) + + + # MCH pivot + self.make_constraint( bones['pivot']['mch'], { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : bones['hips']['mch'][-1], + 'owner_space' : 'LOCAL', + 'target_space' : 'LOCAL' + }) + + # DEF bones + deform = bones['def'] + tweaks = bones['hips']['tweak'] + bones['chest']['tweak'] + tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ] + + for d,t in zip(deform, tweaks): + tidx = tweaks.index(t) + + self.make_constraint( d, { + 'constraint' : 'COPY_TRANSFORMS', + 'subtarget' : t + }) + + if tidx != len(tweaks) - 1: + self.make_constraint( d, { + 'constraint' : 'DAMPED_TRACK', + 'subtarget' : tweaks[ tidx + 1 ], + }) + + self.make_constraint( d, { + 'constraint' : 'STRETCH_TO', + 'subtarget' : tweaks[ tidx + 1 ], + }) + + def stick_to_bendy_bones(self, bones): + bpy.ops.object.mode_set(mode='OBJECT') + deform = bones['def'] + pb = self.obj.pose.bones + + if len(deform) > 1: # Only for single bone sup chain + return + + def_pb = pb[deform[0]] + ctrl_start = pb[bones['chain']['ctrl'][0]] + ctrl_end = pb[bones['chain']['ctrl'][-1]] + mch_start = pb[bones['chain']['mch'][0]] + mch_end = pb[bones['chain']['mch_ctrl'][-1]] + + if 'bbone_custom_handle_start' in dir(def_pb) and 'bbone_custom_handle_end' in dir(def_pb): + if not self.SINGLE_BONE: + def_pb.bbone_custom_handle_start = ctrl_start + def_pb.bbone_custom_handle_end = ctrl_end + else: + def_pb.bbone_custom_handle_start = mch_start + def_pb.bbone_custom_handle_end = mch_end + def_pb.use_bbone_custom_handles = True + + def create_drivers(self, bones): + bpy.ops.object.mode_set(mode ='OBJECT') + pb = self.obj.pose.bones + + # Setting the torso's props + torso = pb[ bones['pivot']['ctrl'] ] + + props = [ "head_follow", "neck_follow" ] + owners = [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ] + + for prop in props: + if prop == 'neck_follow': + torso[prop] = 0.5 + else: + torso[prop] = 0.0 + + prop = rna_idprop_ui_prop_get( torso, prop, create=True ) + prop["min"] = 0.0 + prop["max"] = 1.0 + prop["soft_min"] = 0.0 + prop["soft_max"] = 1.0 + prop["description"] = prop + + # driving the follow rotation switches for neck and head + for bone, prop, in zip( owners, props ): + # Add driver to copy rotation constraint + drv = pb[ bone ].constraints[ 0 ].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + torso.path_from_id() + '['+ '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + def locks_and_widgets(self, bones): + bpy.ops.object.mode_set(mode='OBJECT') + pb = self.obj.pose.bones + + #Locks + mch_ctrl = bones['chain']['mch_ctrl'] + + for b in mch_ctrl: + pb[b].lock_rotation = False, False, False + pb[b].lock_location = False, False, False + pb[b].lock_scale = False, False, False + + for b in bones['chain']['tweak']: + pb[b].lock_rotation = True, False, True + + for b in bones['chain']['ctrl']: + pb[b].lock_rotation = True, False, True + + if 'pivot' in bones.keys(): + pb[bones['pivot']['ctrl']].lock_rotation = True, False, True + + # Assigning a widget to main ctrl bone + if 'pivot' in bones.keys(): + create_cube_widget( + self.obj, + bones['pivot']['ctrl'], + radius = 0.15, + bone_transform_name = None + ) + + for bone in bones['chain']['tweak']: + create_cube_widget( + self.obj, + bone, + radius = 0.2, + bone_transform_name = None + ) + + create_chain_widget( + self.obj, + bones['chain']['ctrl'][0], + invert = False, + radius = 0.3, + bone_transform_name = None + ) + + create_chain_widget( + self.obj, + bones['chain']['ctrl'][-1], + invert = True, + radius = 0.3, + bone_transform_name = None + ) + + if bones['chain']['conv']: + create_cube_widget( + self.obj, + bones['chain']['conv'], + radius = 0.5, + bone_transform_name = None + ) + + # Assigning layers to tweaks and ctrls + for bone in bones['chain']['tweak']: + if self.tweak_layers: + pb[bone].bone.layers = self.tweak_layers + + # for bone in bones['chain']['ctrl']: + # if self.tweak_layers: + # pb[bone].bone.layers = self.tweak_layers + + + return + + + # Locks + tweaks = bones['neck']['tweak'] + bones['chest']['tweak'] + tweaks += bones['hips']['tweak'] + + if 'tail' in bones.keys(): + tweaks += bones['tail']['tweak'] + + # Tweak bones locks + for bone in tweaks: + pb[bone].lock_rotation = True, False, True + pb[bone].lock_scale = False, True, False + + # Widgets + + # Assigning a widget to pivot bone + if 'pivot' in bones.keys(): + create_cube_widget( + self.obj, + bones['pivot']['ctrl'], + radius = 0.5, + bone_transform_name = None + ) + + # Assigning widgets to control bones + gen_ctrls = [ + bones['neck']['ctrl_neck'], + bones['chest']['ctrl'], + bones['hips']['ctrl'] + ] + + if 'tail' in bones.keys(): + gen_ctrls += [ bones['tail']['ctrl'] ] + + for bone in gen_ctrls: + create_circle_widget( + self.obj, + bone, + radius = 1.0, + head_tail = 0.5, + with_line = False, + bone_transform_name = None + ) + + # Head widget + create_circle_widget( + self.obj, + bones['neck']['ctrl'], + radius = 0.75, + head_tail = 1.0, + with_line = False, + bone_transform_name = None + ) + + # place widgets on correct bones + chest_widget_loc = pb[ bones['chest']['mch_wgt'] ] + pb[bones['chest']['ctrl'] ].custom_shape_transform = chest_widget_loc + + hips_widget_loc = pb[bones['hips']['mch_wgt']] + if 'tail' in bones.keys(): + hips_widget_loc = bones['def'][self.tail_pos - 1] + + pb[ bones['hips']['ctrl'] ].custom_shape_transform = hips_widget_loc + + # Assigning widgets to tweak bones and layers + for bone in tweaks: + create_sphere_widget(self.obj, bone, bone_transform_name=None) + + if self.tweak_layers: + pb[bone].bone.layers = self.tweak_layers + + def generate(self): + + # Torso Rig Anatomy: + # Neck: all bones above neck point, last bone is head + # Upper torso: all bones between pivot and neck start + # Lower torso: all bones below pivot until tail point + # Tail: all bones below tail point + + #bone_chains = self.build_bone_structure() + + self.SINGLE_BONE = (len(self.org_bones) == 1) + + bpy.ops.object.mode_set(mode ='EDIT') + eb = self.obj.data.edit_bones + + bones = {} + if eb[self.org_bones[0]].parent: + bones['parent'] = eb[self.org_bones[0]].parent.name + + # Clear parents for org bones + for bone in self.org_bones[0:]: + eb[bone].use_connect = False + eb[bone].parent = None + + #if bone_chains != 'ERROR': + # + # # Create lists of bones and strip "ORG" from their names + # neck_bones = [ strip_org(b) for b in bone_chains['neck' ] ] + # upper_torso_bones = [ strip_org(b) for b in bone_chains['upper'] ] + # lower_torso_bones = [ strip_org(b) for b in bone_chains['lower'] ] + # tail_bones = [ strip_org(b) for b in bone_chains['tail' ] ] + + chain_bones = [strip_org(b) for b in self.org_bones] + + # bones = {} + # + # bones['def'] = self.create_deform() # Gets org bones from self + # bones['pivot'] = self.create_pivot( self.pivot_pos ) + # bones['neck'] = self.create_neck( neck_bones ) + # bones['chest'] = self.create_chest( upper_torso_bones ) + # bones['hips'] = self.create_hips( lower_torso_bones ) + # # TODO: Add create tail + # + # if tail_bones: + # bones['tail'] = self.create_tail( tail_bones ) + + + + bones['def'] = self.create_deform() + if len(self.org_bones) > 2: + bones['pivot'] = self.create_pivot() + bones['chain'] = self.create_chain() + + # Adjust Roll in SINGLE_BONE case + #if self.SINGLE_BONE: + all_bones = bones['chain']['mch'] + bones['chain']['mch_ctrl'] + bones['chain']['ctrl'] + bones['def'] + for b in all_bones: + eb[b].roll = -pi / 2 + + #Todo create pivot-like controls + + # # TEST + # bpy.ops.object.mode_set(mode ='EDIT') + # eb = self.obj.data.edit_bones + # + # self.parent_bones( bones ) + # self.constrain_bones( bones ) + # self.create_drivers( bones ) + # self.locks_and_widgets( bones ) + + self.parent_bones(bones) + self.constrain_bones(bones) + self.stick_to_bendy_bones(bones) + self.locks_and_widgets(bones) + + #Todo invoke the remaining functions + + # controls = [ bones['neck']['ctrl'], bones['neck']['ctrl_neck'] ] + # controls += [ bones['chest']['ctrl'], bones['hips']['ctrl'] ] + # controls += [ bones['pivot']['ctrl'] ] + + # if 'tail' in bones.keys(): + # controls += [ bones['tail']['ctrl'] ] + + return #TODO modify what follows + + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) #TODO correct this + return [script % ( + controls_string, + bones['pivot']['ctrl'], + 'head_follow', + 'neck_follow' + )] + + +def add_parameters(params): + """ Add the parameters of this rig type to the + RigifyParameters PropertyGroup + """ + + items = [ + ('auto', 'Auto', ''), + ('x', 'X', ''), + ('y', 'Y', ''), + ('z', 'Z', '') + ] + + params.tweak_axis = bpy.props.EnumProperty( + items = items, + name = "Tweak Axis", + default = 'auto' + ) + + params.conv_bone = bpy.props.StringProperty( + name = 'Convergence bone', + default = '' + ) + + params.bbones = bpy.props.IntProperty( + name = 'bbone segments', + default = 10, + min = 1, + description = 'Number of segments' + ) + + # params.neck_pos = bpy.props.IntProperty( + # name = 'neck_position', + # default = 6, + # min = 0, + # description = 'Neck start position' + # ) + # + # params.pivot_pos = bpy.props.IntProperty( + # name = 'pivot_position', + # default = 3, + # min = 0, + # description = 'Position of the torso control and pivot point' + # ) + # + # params.tail_pos = bpy.props.IntProperty( + # name = 'tail_position', + # default = 0, + # min = 0, + # description = 'Where the tail starts (change from 0 to enable)' + # ) + + # Setting up extra layers for the FK and tweak + params.tweak_extra_layers = bpy.props.BoolProperty( + name = "tweak_extra_layers", + default = True, + description = "" + ) + + params.tweak_layers = bpy.props.BoolVectorProperty( + size = 32, + description = "Layers for the tweak controls to be on", + default = tuple( [ i == 1 for i in range(0, 32) ] ) + ) + + +def parameters_ui(layout, params): + """ Create the ui for the rig parameters.""" + + # r = layout.row() + # r.prop(params, "neck_pos") + # + # r = layout.row() + # r.prop(params, "pivot_pos") + # + # r = layout.row() + # r.prop(params, "tail_pos") + + # r = layout.row() + # r.prop(params, "control_num") + + pb = bpy.context.object.pose + + r = layout.row() + col = r.column(align=True) + row = col.row(align=True) + row.prop(params, "tweak_axis", expand=True) + # for i,axis in enumerate( [ 'x', 'y', 'z' ] ): + # row.prop(params, "tweak_axis", index=i, toggle=True, text=axis) + + r = layout.row() + r.prop(params, "bbones") + + r = layout.row() + r.prop_search(params, 'conv_bone', pb, "bones", text="Convergence Bone") + + r = layout.row() + r.prop(params, "tweak_extra_layers") + r.active = params.tweak_extra_layers + + col = r.column(align=True) + row = col.row(align=True) + + for i in range(8): + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range(16,24): + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + col = r.column(align=True) + row = col.row(align=True) + + for i in range(8,16): + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + row = col.row(align=True) + + for i in range(24,32): + row.prop(params, "tweak_layers", index=i, toggle=True, text="") + + +def create_sample(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + bones = {} + + bone = arm.edit_bones.new('spine') + bone.head[:] = 0.0000, 0.0000, 0.0000 + bone.tail[:] = 0.0000, 0.5000/8, 1.0000/8 + bone.roll = 0.0000 + bone.use_connect = False + bones['spine'] = bone.name + bone = arm.edit_bones.new('spine.001') + bone.head[:] = 0.0000, 0.5000/8, 1.0000/8 + bone.tail[:] = 0.0000, 0.7500/8, 2.0000/8 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine']] + bones['spine.001'] = bone.name + bone = arm.edit_bones.new('spine.002') + bone.head[:] = 0.0000, 0.7500/8, 2.0000/8 + bone.tail[:] = 0.0000, 0.5000/8, 3.0000/8 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.001']] + bones['spine.002'] = bone.name + bone = arm.edit_bones.new('spine.003') + bone.head[:] = 0.0000, 0.5000/8, 3.0000/8 + bone.tail[:] = 0.0000, 0.0000, 4.0000/8 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['spine.002']] + bones['spine.003'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['spine']] + pbone.rigify_type = 'experimental.super_chain' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.001']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.002']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + pbone = obj.pose.bones[bones['spine.003']] + pbone.rigify_type = '' + pbone.lock_location = (False, False, False) + pbone.lock_rotation = (False, False, False) + pbone.lock_rotation_w = False + pbone.lock_scale = (False, False, False) + pbone.rotation_mode = 'QUATERNION' + pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] + + bpy.ops.object.mode_set(mode='EDIT') + for bone in arm.edit_bones: + bone.select = False + bone.select_head = False + bone.select_tail = False + for b in bones: + bone = arm.edit_bones[bones[b]] + bone.select = True + bone.select_head = True + bone.select_tail = True + arm.edit_bones.active = bone + + arm.layers = [(x in [0]) for x in range(32)] \ No newline at end of file diff --git a/rigify/rigs/experimental/super_eye.py b/rigify/rigs/experimental/super_eye.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/faces/__init__.py b/rigify/rigs/faces/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/faces/super_face.py b/rigify/rigs/faces/super_face.py new file mode 100644 index 0000000000000000000000000000000000000000..ae12ecf6eac323d044d91235642785da31452439 --- /dev/null +++ b/rigify/rigs/faces/super_face.py @@ -0,0 +1,2396 @@ +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 ..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 + + 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'] + + # eyes ctrls + eyeL_e = eb[bones['eyes'][0]] + eyeR_e = eb[bones['eyes'][1]] + + interpupillary_distance = eyeL_e.head - eyeR_e.head + distance = (eyeL_e.head - eyeR_e.head) * 3 + distance = distance.cross((0, 0, 1)) + + 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, eyeL_e.length * 1.35 ] ) + bone.tail[:] = bone.head + Vector([0, 0, interpupillary_distance.length * 0.3144]) + + ## 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 = 'faces.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/rigs/limbs/__init__.py b/rigify/rigs/limbs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/pitchipoy/limbs/super_arm.py b/rigify/rigs/limbs/arm.py similarity index 66% rename from rigify/rigs/pitchipoy/limbs/super_arm.py rename to rigify/rigs/limbs/arm.py index 1f84c6d5a2ca8ed96edb5747f3ea9f90cbf3051c..1a560c46a5e3605f7b8e540c8da85a2477b14181 100644 --- a/rigify/rigs/pitchipoy/limbs/super_arm.py +++ b/rigify/rigs/limbs/arm.py @@ -1,41 +1,48 @@ import bpy, re -from ..super_widgets import create_hand_widget +from ..widgets import create_hand_widget, create_gear_widget 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 ...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, create_line_widget +from ...utils import MetarigError, make_mechanism_name, org +from ...utils import create_limb_widget, connected_children_names +from ...utils import align_bone_y_axis from rna_prop_ui import rna_idprop_ui_prop_get -from ..super_widgets import create_ikarrow_widget -from math import trunc +from ..widgets import create_ikarrow_widget +from math import trunc, pi extra_script = """ controls = [%s] ctrl = '%s' if is_selected( controls ): + layout.prop( pose_bones[ ctrl ], '["%s"]') layout.prop( pose_bones[ ctrl ], '["%s"]') if '%s' in pose_bones[ctrl].keys(): layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) """ +IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class + # add_parameters and parameters_ui are unused for implementation classes + + class Rig: + def __init__(self, obj, bone_name, params): """ Initialize arm rig and key rig properties """ - self.obj = obj - self.params = params + self.obj = obj + self.params = params self.org_bones = list( [bone_name] + connected_children_names(obj, bone_name) )[:3] # The basic limb is the first 3 bones - self.segments = params.segments - self.bbones = params.bbones + self.segments = params.segments + self.bbones = params.bbones self.limb_type = params.limb_type - self.rot_axis = params.rotation_axis + self.rot_axis = params.rotation_axis # Assign values to tweak/FK layers props if opted by user if params.tweak_extra_layers: @@ -52,7 +59,7 @@ class Rig: org_bones = self.org_bones - bpy.ops.object.mode_set(mode ='EDIT') + bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones name = get_bone_name( strip_org( org_bones[0] ), 'mch', 'parent' ) @@ -65,6 +72,13 @@ class Rig: eb[ mch ].roll = 0.0 + # Add non-MCH main limb control + name = get_bone_name(strip_org(org_bones[0]), 'ctrl', 'parent') + main_parent = copy_bone(self.obj, org_bones[0], name) + eb[main_parent].length = eb[org_bones[0]].length / 4 + eb[main_parent].parent = None + eb[main_parent].roll = 0.0 + # Constraints make_constraint( self, mch, { 'constraint' : 'COPY_ROTATION', @@ -81,26 +95,31 @@ class Rig: name = 'FK_limb_follow' - pb[ mch ][ name ] = 0.0 - prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + # pb[ mch ][ name ] = 0.0 + # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + pb[main_parent][name] = 0.0 + prop = rna_idprop_ui_prop_get(pb[main_parent], name, create=True) - prop["min"] = 0.0 - prop["max"] = 1.0 - prop["soft_min"] = 0.0 - prop["soft_max"] = 1.0 + 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 = 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() + \ + var.targets[0].data_path = pb[main_parent].path_from_id() + \ '[' + '"' + name + '"' + ']' - return mch + size = pb[main_parent].bone.y_axis.length * 10 + create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None) + + return [mch, main_parent] def create_tweak(self): org_bones = self.org_bones @@ -114,14 +133,7 @@ class Rig: # Create and parent mch and ctrl tweaks for i,org in enumerate(org_bones): - - #if (self.limb_type == 'paw'): - # idx_stop = len(org_bones) - #else: - # idx_stop = len(org_bones) - 1 - if i < len(org_bones) - 1: - # if i < idx_stop: # Create segments if specified for j in range( self.segments ): # MCH @@ -234,26 +246,25 @@ class Rig: eb = self.obj.data.edit_bones def_bones = [] - for i,org in enumerate(org_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 ) + 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 + 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) + put_bone(self.obj, def_name, eb[ def_bones[-1] ].tail) - def_bones += [ def_name ] + 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 ) + 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 ): @@ -285,9 +296,9 @@ class Rig: 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[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_in = 0.0 self.obj.data.bones[ def_bones[-1] ].bbone_out = 0.0 @@ -361,17 +372,71 @@ class Rig: # Parenting eb[ ctrl ].parent = eb[ parent ] eb[ mch_str ].parent = eb[ parent ] - eb[ mch_ik ].parent = eb[ ctrl ] + # Make standard pole target bone + pole_name = get_bone_name(org_bones[0], 'ctrl', 'ik_target') + pole_target = copy_bone(self.obj, org_bones[0], pole_name) + + lo_vector = eb[org_bones[1]].tail - eb[org_bones[1]].head + tot_vector = eb[org_bones[0]].head - eb[org_bones[1]].tail + tot_vector.normalize() + elbow_vector = lo_vector.dot(tot_vector)*tot_vector - lo_vector # elbow_vec as regression of lo on tot + elbow_vector.normalize() + elbow_vector *= (eb[org_bones[1]].tail - eb[org_bones[0]].head).length + z_vector = eb[org_bones[0]].z_axis + eb[org_bones[1]].z_axis + alfa = elbow_vector.angle(z_vector) + + if alfa > pi/2: + pole_angle = -pi/2 + else: + pole_angle = pi/2 + + eb[pole_target].head = eb[org_bones[0]].tail + elbow_vector + eb[pole_target].tail = eb[pole_target].head - elbow_vector/8 + eb[pole_target].roll = 0.0 + + # Make visual pole + vispole_name = 'VIS_' + get_bone_name(org_bones[0], 'ctrl', 'ik_pole') + vispole = copy_bone(self.obj, org_bones[1], vispole_name) + eb[vispole].tail = eb[vispole].head + Vector((0.0, 0.0, eb[org_bones[1]].length/10)) + eb[vispole].use_connect = False + eb[vispole].hide_select = True + eb[vispole].parent = None + + make_constraint(self, mch_ik, { + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) - make_constraint( self, mch_ik, { - 'constraint' : 'IK', - 'subtarget' : mch_target, - 'chain_count' : 2, + make_constraint(self, mch_ik, { # 2_nd IK for pole targeted chain + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) + + # VIS pole constraints + make_constraint(self, vispole, { + 'constraint': 'COPY_LOCATION', + 'name': 'copy_loc', + 'subtarget': org_bones[1], }) pb = self.obj.pose.bones + + make_constraint(self, vispole, { + 'constraint': 'STRETCH_TO', + 'name': 'stretch_to', + 'subtarget': pole_target, + 'volume': 'NO_VOLUME', + 'rest_length': pb[vispole].length + }) + + pb[mch_ik].constraints[-1].pole_target = self.obj + pb[mch_ik].constraints[-1].pole_subtarget = pole_target + pb[mch_ik].constraints[-1].pole_angle = pole_angle + pb[ mch_ik ].ik_stretch = 0.1 pb[ ctrl ].ik_stretch = 0.1 @@ -383,53 +448,55 @@ class Rig: # 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 + create_sphere_widget(self.obj, pole_target, bone_transform_name=None) + create_line_widget(self.obj, vispole) + + return {'ctrl': {'limb': ctrl, 'ik_target': pole_target}, + 'mch_ik': mch_ik, + 'mch_target': mch_target, + 'mch_str': mch_str, + 'visuals': {'vispole': vispole} } def create_fk(self, parent): org_bones = self.org_bones.copy() - - bpy.ops.object.mode_set(mode ='EDIT') + 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 ) + 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' ) + self.obj, org_bones[-1], get_bone_name(o, 'mch', 'fk') ) - eb[ mch ].length /= 4 + 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 + 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' + 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 + pb[ctrls[2]].lock_location = True, True, True - create_limb_widget( self.obj, ctrls[0] ) - create_limb_widget( self.obj, ctrls[1] ) + 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) @@ -437,43 +504,43 @@ class Rig: if self.fk_layers: pb[c].bone.layers = self.fk_layers - return { 'ctrl' : ctrls, 'mch' : mch } + return {'ctrl': ctrls, 'mch': mch} - def org_parenting_and_switch(self, org, ik, fk, parent): - bpy.ops.object.mode_set(mode ='EDIT') + def org_parenting_and_switch(self, org_bones, 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): + for i, o in enumerate(org_bones): if i > 0: - eb[o].parent = eb[ org[i-1] ] - if i <= len(org)-1: + eb[o].parent = eb[org_bones[i-1]] + if i <= len(org_bones)-1: eb[o].use_connect = True - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones - pb_parent = pb[ parent ] + 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 + 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'] ] + iks = [ik['ctrl']['limb']] + iks += [ik[k] for k in ['mch_ik', 'mch_target']] - for o, i, f in zip( org, iks, fk ): + for o, i, f in zip(org_bones, iks, fk): make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : i + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': i }) - make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : f + make_constraint(self, o, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': f }) # Add driver to relevant constraint @@ -485,18 +552,19 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' - def create_arm( self, bones): + def create_arm(self, bones): org_bones = self.org_bones bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones - ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) + pole_target = get_bone_name(org_bones[0], 'ctrl', 'ik_target') # Create IK arm control - ctrl = copy_bone( self.obj, org_bones[2], ctrl ) + ctrl = get_bone_name(org_bones[2], 'ctrl', 'ik') + ctrl = copy_bone(self.obj, org_bones[2], ctrl) # clear parent (so that rigify will parent to root) eb[ ctrl ].parent = None @@ -512,6 +580,12 @@ class Rig: eb[ctrl_socket].parent = None eb[ctrl].parent = eb[ctrl_socket] + # MCH for pole ik control + ctrl_pole_socket = copy_bone(self.obj, org_bones[2], get_bone_name(org_bones[2], 'mch', 'pole_ik_socket')) + eb[ctrl_pole_socket].tail = eb[ctrl_pole_socket].head + 0.8 * (eb[ctrl_pole_socket].tail - eb[ctrl_pole_socket].head) + eb[ctrl_pole_socket].parent = None + eb[pole_target].parent = eb[ctrl_pole_socket] + ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) eb[ctrl_root].use_connect = False @@ -522,10 +596,20 @@ class Rig: ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent + if eb[org_bones[0]].parent_recursive: + eb[ctrl_parent].parent = eb[org_bones[0]].parent_recursive[-1] + else: + eb[ctrl_parent].parent = eb[org_bones[0]].parent else: arm_parent = None + mch_name = get_bone_name(strip_org(org_bones[0]), 'mch', 'parent_socket') + mch_main_parent = copy_bone(self.obj, org_bones[0], mch_name) + eb[mch_main_parent].length = eb[org_bones[0]].length / 12 + eb[mch_main_parent].parent = eb[bones['parent']] + eb[mch_main_parent].roll = 0.0 + eb[bones['main_parent']].parent = eb[mch_main_parent] + # Set up constraints # Constrain ik ctrl to root / parent @@ -535,41 +619,57 @@ class Rig: 'subtarget' : ctrl_root, }) + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': ctrl_root, + }) + if arm_parent: make_constraint( self, ctrl_socket, { 'constraint' : 'COPY_TRANSFORMS', 'subtarget' : ctrl_parent, }) - # Constrain mch target bone to the ik control and mch stretch + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': ctrl_parent, + }) + # Constrain mch target bone to the ik control and mch stretch make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', 'subtarget' : bones['ik']['mch_str'], 'head_tail' : 1.0 }) - # Constrain mch ik stretch bone to the ik control - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'DAMPED_TRACK', - 'subtarget' : ctrl, + make_constraint(self, bones['ik']['mch_str'], { + 'constraint': 'DAMPED_TRACK', + 'subtarget': ctrl, + }) + make_constraint(self, bones['ik']['mch_str'], { + 'constraint': 'STRETCH_TO', + 'subtarget': ctrl, }) - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'STRETCH_TO', - 'subtarget' : ctrl, + make_constraint(self, bones['ik']['mch_str'], { + 'constraint': 'LIMIT_SCALE', + 'use_min_y': True, + 'use_max_y': True, + 'max_y': 1.05, + 'owner_space': 'LOCAL' }) - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'LIMIT_SCALE', - 'use_min_y' : True, - 'use_max_y' : True, - 'max_y' : 1.05, - 'owner_space' : 'LOCAL' + make_constraint(self, mch_main_parent, { + 'constraint': 'COPY_ROTATION', + 'subtarget': org_bones[0] }) - # Create ik/fk switch property pb = self.obj.pose.bones - pb_parent = pb[ bones['parent'] ] + + # Create ik/fk switch property + pb_parent = pb[bones['main_parent']] + pb_parent.lock_location = True, True, True + pb_parent.lock_rotation = True, True, True + pb_parent.lock_scale = True, True, True # Modify rotation mode for ik and tweak controls pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY' @@ -577,17 +677,17 @@ class Rig: for b in bones['tweak']['ctrl']: pb[b].rotation_mode = 'ZXY' - 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 + pb_parent['IK_Stretch'] = 1.0 + prop = rna_idprop_ui_prop_get(pb_parent, 'IK_Stretch', 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 + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver drv.type = 'SUM' var = drv.variables.new() @@ -595,45 +695,137 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - drv_modifier.mode = 'POLYNOMIAL' - drv_modifier.poly_order = 1 + 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(self.obj, ctrl, bone_transform_name=None) - bones['ik']['ctrl']['terminal'] = [ ctrl ] + bones['ik']['ctrl']['terminal'] = [ctrl] if arm_parent: - bones['ik']['mch_hand'] = [ctrl_socket, ctrl_root, ctrl_parent] + bones['ik']['mch_hand'] = [ctrl_socket, ctrl_pole_socket, ctrl_root, ctrl_parent] else: - bones['ik']['mch_hand'] = [ctrl_socket, ctrl_root] + bones['ik']['mch_hand'] = [ctrl_socket, ctrl_pole_socket, ctrl_root] return bones def create_drivers(self, bones): - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones ctrl = pb[bones['ik']['mch_hand'][0]] + ctrl_pole = pb[bones['ik']['mch_hand'][1]] + + #owner = pb[bones['ik']['ctrl']['limb']] + owner = pb[bones['main_parent']] - props = [ "IK_follow", "root/parent" ] + props = ["IK_follow", "root/parent", "pole_vector", "pole_follow"] for prop in props: - if prop == 'IK_follow': - ctrl[prop]=True - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = False - rna_prop["max"] = True + if prop == 'pole_vector': + owner[prop] = False + pole_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + pole_prop["min"] = False + pole_prop["max"] = True + pole_prop["description"] = prop + mch_ik = pb[bones['ik']['mch_ik']] + + # ik target hide driver + pole_target = pb[bones['ik']['ctrl']['ik_target']] + drv = pole_target.bone.driver_add("hide").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 = \ + owner.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 + + # vis-pole hide driver + vispole = pb[bones['ik']['visuals']['vispole']] + drv = vispole.bone.driver_add("hide").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 = \ + owner.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 + + # arrow hide driver + # pole_target = pb[bones['ik']['ctrl']['limb']] + # drv = pole_target.bone.driver_add("hide").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 = \ + # owner.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] = 0.0 + # drv_modifier.coefficients[1] = 1.0 + + for cns in mch_ik.constraints: + if 'IK' in cns.type: + drv = cns.driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + if not cns.pole_subtarget: + drv_modifier.coefficients[0] = 0.0 + drv_modifier.coefficients[1] = 1 + else: + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'IK_follow': + + owner[prop] = True + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = False + rna_prop["max"] = True rna_prop["description"] = prop - drv = ctrl.constraints[ 0 ].driver_add("mute").driver + drv = ctrl.constraints[0].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -641,17 +833,17 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.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.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 if len(ctrl.constraints) > 1: - drv = ctrl.constraints[ 1 ].driver_add("mute").driver + drv = ctrl.constraints[1].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -659,42 +851,16 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.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.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 - elif len(ctrl.constraints) > 1: - ctrl[prop]=0.0 - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = 0.0 - rna_prop["max"] = 1.0 - rna_prop["soft_min"] = 0.0 - rna_prop["soft_max"] = 1.0 - rna_prop["description"] = prop - - # drv = ctrl.constraints[ 0 ].driver_add("influence").driver - # drv.type = 'AVERAGE' - # - # var = drv.variables.new() - # var.name = prop - # var.type = "SINGLE_PROP" - # var.targets[0].id = self.obj - # var.targets[0].data_path = \ - # ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - # - # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - # - # drv_modifier.mode = 'POLYNOMIAL' - # drv_modifier.poly_order = 1 - # drv_modifier.coefficients[0] = 1.0 - # drv_modifier.coefficients[1] = -1.0 - - drv = ctrl.constraints[ 1 ].driver_add("influence").driver + drv = ctrl_pole.constraints[0].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -702,43 +868,109 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + if len(ctrl_pole.constraints) > 1: + drv = ctrl_pole.constraints[1].driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'root/parent': + if len(ctrl.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + elif prop == 'pole_follow': + if len(ctrl_pole.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl_pole.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' def generate(self): - bpy.ops.object.mode_set(mode ='EDIT') - eb = self.obj.data.edit_bones + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones - # Clear parents for org bones - for bone in self.org_bones[1:]: - eb[bone].use_connect = False - eb[bone].parent = None + # Clear parents for org bones + for bone in self.org_bones[1:]: + eb[bone].use_connect = False + eb[bone].parent = None - bones = {} + bones = {} - # Create mch limb parent - bones['parent'] = self.create_parent() - bones['tweak'] = self.create_tweak() - bones['def'] = self.create_def( bones['tweak']['ctrl'] ) - bones['ik'] = self.create_ik( bones['parent'] ) - bones['fk'] = self.create_fk( bones['parent'] ) + # Create mch limb parent + mch_parent, main_parent = self.create_parent() + bones['parent'] = mch_parent + bones['main_parent'] = main_parent + bones['tweak'] = self.create_tweak() + bones['def'] = self.create_def(bones['tweak']['ctrl']) + bones['ik'] = self.create_ik(bones['parent']) + bones['fk'] = self.create_fk(bones['parent']) - self.org_parenting_and_switch( - self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent'] - ) + self.org_parenting_and_switch(self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['main_parent']) - bones = self.create_arm( bones ) - self.create_drivers( bones ) + bones = self.create_arm(bones) + self.create_drivers(bones) - controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][0] ] + controls = [bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][0]] + controls.append(bones['main_parent']) - # Create UI - controls_string = ", ".join(["'" + x + "'" for x in controls]) + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) - script = create_script( bones, 'arm' ) - script += extra_script % (controls_string, bones['ik']['mch_hand'][0], 'IK_follow', 'root/parent', 'root/parent') + script = create_script(bones, 'arm') + script += extra_script % (controls_string, bones['main_parent'], 'IK_follow', 'pole_follow', 'root/parent', 'root/parent') - return [ script ] + return [script] def add_parameters(params): @@ -848,7 +1080,7 @@ def create_sample(obj): bones = {} - for _ in range(28): + for _ in range(29): arm.rigify_layers.add() arm.rigify_layers[5].name = 'Fingers' @@ -861,6 +1093,8 @@ def create_sample(obj): arm.rigify_layers[8].row = 8 arm.rigify_layers[9].name = 'Arm.L (Tweak)' arm.rigify_layers[9].row = 9 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 bone = arm.edit_bones.new('upper_arm.L') bone.head[:] = 0.1953, 0.0267, 1.5846 @@ -1018,7 +1252,7 @@ def create_sample(obj): bpy.ops.object.mode_set(mode='OBJECT') pbone = obj.pose.bones[bones['upper_arm.L']] - pbone.rigify_type = 'pitchipoy.limbs.super_limb' + pbone.rigify_type = 'limbs.super_limb' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1091,7 +1325,7 @@ def create_sample(obj): pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'YXZ' pbone = obj.pose.bones[bones['f_index.01.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1110,7 +1344,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['thumb.01.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1129,7 +1363,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_middle.01.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1148,7 +1382,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_ring.01.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1167,7 +1401,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_pinky.01.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False diff --git a/rigify/rigs/pitchipoy/limbs/super_leg.py b/rigify/rigs/limbs/leg.py similarity index 63% rename from rigify/rigs/pitchipoy/limbs/super_leg.py rename to rigify/rigs/limbs/leg.py index 06df1c741453abd46af839fde0d18ceda1d03aaf..e60f2c683a4902d31f18453033874924c60a4505 100644 --- a/rigify/rigs/pitchipoy/limbs/super_leg.py +++ b/rigify/rigs/limbs/leg.py @@ -1,45 +1,49 @@ import bpy, re, math -from ..super_widgets import create_foot_widget, create_ballsocket_widget -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 +from ..widgets import create_foot_widget, create_ballsocket_widget, create_gear_widget +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, create_line_widget +from ...utils import MetarigError, make_mechanism_name, org +from ...utils import create_limb_widget, connected_children_names +from ...utils import align_bone_y_axis, align_bone_x_axis, align_bone_roll +from rna_prop_ui import rna_idprop_ui_prop_get +from ..widgets import create_ikarrow_widget +from math import trunc, pi extra_script = """ controls = [%s] ctrl = '%s' if is_selected( controls ): + layout.prop( pose_bones[ ctrl ], '["%s"]') layout.prop( pose_bones[ ctrl ], '["%s"]') if '%s' in pose_bones[ctrl].keys(): layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) """ +IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class + # add_parameters and parameters_ui are unused for implementation classes + + class Rig: + def __init__(self, obj, bone_name, params): """ Initialize leg rig and key rig properties """ - self.obj = obj - self.params = params + self.obj = obj + self.params = params self.org_bones = list( [bone_name] + connected_children_names(obj, bone_name) )[:3] # The basic limb is the first 3 bones - self.segments = params.segments - self.bbones = params.bbones + self.segments = params.segments + self.bbones = params.bbones self.limb_type = params.limb_type - self.rot_axis = params.rotation_axis + self.rot_axis = params.rotation_axis # Assign values to tweak/FK layers props if opted by user if params.tweak_extra_layers: @@ -52,11 +56,11 @@ class Rig: else: self.fk_layers = None - def create_parent( self ): + def create_parent(self): org_bones = self.org_bones - bpy.ops.object.mode_set(mode ='EDIT') + bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones name = get_bone_name( strip_org( org_bones[0] ), 'mch', 'parent' ) @@ -69,6 +73,13 @@ class Rig: eb[ mch ].roll = 0.0 + # Add non-MCH main limb control + name = get_bone_name(strip_org(org_bones[0]), 'ctrl', 'parent') + main_parent = copy_bone(self.obj, org_bones[0], name) + eb[main_parent].length = eb[org_bones[0]].length / 4 + eb[main_parent].parent = eb[org_bones[0]] + eb[main_parent].roll = 0.0 + # Constraints make_constraint( self, mch, { 'constraint' : 'COPY_ROTATION', @@ -85,28 +96,33 @@ class Rig: name = 'FK_limb_follow' - pb[ mch ][ name ] = 0.0 - prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + # pb[ mch ][ name ] = 0.0 + # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + pb[main_parent][name] = 0.0 + prop = rna_idprop_ui_prop_get(pb[main_parent], name, create=True) - prop["min"] = 0.0 - prop["max"] = 1.0 - prop["soft_min"] = 0.0 - prop["soft_max"] = 1.0 + 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 = 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() + \ + var.targets[0].data_path = pb[main_parent].path_from_id() + \ '[' + '"' + name + '"' + ']' - return mch + size = pb[main_parent].bone.y_axis.length * 10 + create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None) - def create_tweak( self ): + return [mch, main_parent] + + def create_tweak(self): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -118,14 +134,7 @@ class Rig: # Create and parent mch and ctrl tweaks for i,org in enumerate(org_bones): - - #if (self.limb_type == 'paw'): - # idx_stop = len(org_bones) - #else: - # idx_stop = len(org_bones) - 1 - if i < len(org_bones) - 1: - # if i < idx_stop: # Create segments if specified for j in range( self.segments ): # MCH @@ -231,33 +240,32 @@ class Rig: return tweaks - def create_def( self, tweaks ): + def create_def(self, tweaks): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones def_bones = [] - for i,org in enumerate(org_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 ) + 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 + 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) + put_bone(self.obj, def_name, eb[ def_bones[-1] ].tail) - def_bones += [ def_name ] + 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 ) + 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 ): @@ -289,9 +297,9 @@ class Rig: 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[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_in = 0.0 self.obj.data.bones[ def_bones[-1] ].bbone_out = 0.0 @@ -337,7 +345,7 @@ class Rig: return def_bones - def create_ik( self, parent ): + def create_ik(self, parent): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') @@ -365,17 +373,71 @@ class Rig: # Parenting eb[ ctrl ].parent = eb[ parent ] eb[ mch_str ].parent = eb[ parent ] - eb[ mch_ik ].parent = eb[ ctrl ] + # Make standard pole target bone + pole_name = get_bone_name(org_bones[0], 'ctrl', 'ik_target') + pole_target = copy_bone(self.obj, org_bones[0], pole_name) + + lo_vector = eb[org_bones[1]].tail - eb[org_bones[1]].head + tot_vector = eb[org_bones[0]].head - eb[org_bones[1]].tail + tot_vector.normalize() + elbow_vector = lo_vector.dot(tot_vector)*tot_vector - lo_vector # elbow_vec as regression of lo on tot + elbow_vector.normalize() + elbow_vector *= (eb[org_bones[1]].tail - eb[org_bones[0]].head).length + z_vector = eb[org_bones[0]].z_axis + eb[org_bones[1]].z_axis + alfa = elbow_vector.angle(z_vector) + + if alfa > pi/2: + pole_angle = -pi/2 + else: + pole_angle = pi/2 + + eb[pole_target].head = eb[org_bones[0]].tail + elbow_vector + eb[pole_target].tail = eb[pole_target].head - elbow_vector/8 + eb[pole_target].roll = 0.0 + + # Make visual pole + vispole_name = 'VIS_' + get_bone_name(org_bones[0], 'ctrl', 'ik_pole') + vispole = copy_bone(self.obj, org_bones[1], vispole_name) + eb[vispole].tail = eb[vispole].head + Vector((0.0, 0.0, eb[org_bones[1]].length/10)) + eb[vispole].use_connect = False + eb[vispole].hide_select = True + eb[vispole].parent = None + + make_constraint(self, mch_ik, { + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) + + make_constraint(self, mch_ik, { # 2_nd IK for pole targeted chain + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) - make_constraint( self, mch_ik, { - 'constraint' : 'IK', - 'subtarget' : mch_target, - 'chain_count' : 2, + # VIS pole constraints + make_constraint(self, vispole, { + 'constraint': 'COPY_LOCATION', + 'name': 'copy_loc', + 'subtarget': org_bones[1], }) pb = self.obj.pose.bones + + make_constraint(self, vispole, { + 'constraint': 'STRETCH_TO', + 'name': 'stretch_to', + 'subtarget': pole_target, + 'volume': 'NO_VOLUME', + 'rest_length': pb[vispole].length + }) + + pb[mch_ik].constraints[-1].pole_target = self.obj + pb[mch_ik].constraints[-1].pole_subtarget = pole_target + pb[mch_ik].constraints[-1].pole_angle = pole_angle + pb[ mch_ik ].ik_stretch = 0.1 pb[ ctrl ].ik_stretch = 0.1 @@ -387,53 +449,55 @@ class Rig: # 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 + create_sphere_widget(self.obj, pole_target, bone_transform_name=None) + create_line_widget(self.obj, vispole) + + return {'ctrl': {'limb': ctrl, 'ik_target': pole_target}, + 'mch_ik': mch_ik, + 'mch_target': mch_target, + 'mch_str': mch_str, + 'visuals': {'vispole': vispole} } - def create_fk( self, parent ): + def create_fk(self, parent): org_bones = self.org_bones.copy() - - bpy.ops.object.mode_set(mode ='EDIT') + 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 ) + 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' ) + self.obj, org_bones[-1], get_bone_name(o, 'mch', 'fk') ) - eb[ mch ].length /= 4 + 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 + 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' + 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 + pb[ctrls[2]].lock_location = True, True, True - create_limb_widget( self.obj, ctrls[0] ) - create_limb_widget( self.obj, ctrls[1] ) + 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) @@ -441,43 +505,43 @@ class Rig: if self.fk_layers: pb[c].bone.layers = self.fk_layers - return { 'ctrl' : ctrls, 'mch' : mch } + return {'ctrl': ctrls, 'mch': mch} - def org_parenting_and_switch( self, org, ik, fk, parent ): - bpy.ops.object.mode_set(mode ='EDIT') + def org_parenting_and_switch(self, org_bones, 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): + for i, o in enumerate(org_bones): if i > 0: - eb[o].parent = eb[ org[i-1] ] - if i <= len(org)-1: + eb[o].parent = eb[org_bones[i-1]] + if i <= len(org_bones)-1: eb[o].use_connect = True - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones - pb_parent = pb[ parent ] + 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 + 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'] ] + iks = [ik['ctrl']['limb']] + iks += [ik[k] for k in ['mch_ik', 'mch_target']] - for o, i, f in zip( org, iks, fk ): + for o, i, f in zip(org_bones, iks, fk): make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : i + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': i }) - make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : f + make_constraint(self, o, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': f }) # Add driver to relevant constraint @@ -489,9 +553,9 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' - def create_leg( self, bones ): + def create_leg(self, bones): org_bones = list( [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) ) @@ -502,7 +566,7 @@ class Rig: eb = self.obj.data.edit_bones # Create toes def bone - toes_def = get_bone_name( org_bones[-1], 'def' ) + toes_def = get_bone_name(org_bones[-1], 'def') toes_def = copy_bone( self.obj, org_bones[-1], toes_def ) eb[ toes_def ].use_connect = False @@ -511,6 +575,8 @@ class Rig: bones['def'] += [ toes_def ] + pole_target = get_bone_name(org_bones[0], 'ctrl', 'ik_target') + # Create IK leg control ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) ctrl = copy_bone( self.obj, org_bones[2], ctrl ) @@ -525,6 +591,12 @@ class Rig: eb[ctrl_socket].parent = None eb[ctrl].parent = eb[ctrl_socket] + # MCH for pole ik control + ctrl_pole_socket = copy_bone(self.obj, org_bones[2], get_bone_name(org_bones[2], 'mch', 'pole_ik_socket')) + eb[ctrl_pole_socket].tail = eb[ctrl_pole_socket].head + 0.8 * (eb[ctrl_pole_socket].tail - eb[ctrl_pole_socket].head) + eb[ctrl_pole_socket].parent = None + eb[pole_target].parent = eb[ctrl_pole_socket] + ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) eb[ctrl_root].use_connect = False @@ -535,20 +607,27 @@ class Rig: ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent + if eb[org_bones[0]].parent_recursive: + eb[ctrl_parent].parent = eb[org_bones[0]].parent_recursive[-1] + else: + eb[ctrl_parent].parent = eb[org_bones[0]].parent else: leg_parent = None # Create heel ctrl bone - heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) + heel = get_bone_name(org_bones[2], 'ctrl', 'heel_ik') heel = copy_bone( self.obj, org_bones[2], heel ) - orient_bone( self, eb[ heel ], 'y', 0.5 ) - eb[ heel ].length = eb[ org_bones[2] ].length / 2 + # orient_bone( self, eb[ heel ], 'y', 0.5 ) + ax = eb[org_bones[2]].head - eb[org_bones[2]].tail + ax[2] = 0 + align_bone_y_axis(self.obj, heel, ax) + align_bone_x_axis(self.obj, heel, eb[org_bones[2]].x_axis) + eb[heel].length = eb[org_bones[2]].length / 2 # Reset control position and orientation - l = eb[ ctrl ].length - orient_bone( self, eb[ ctrl ], 'y', reverse = True ) - eb[ ctrl ].length = l + l = eb[ctrl].length + orient_bone(self, eb[ctrl], 'y', reverse=True) + eb[ctrl].length = l # Parent eb[ heel ].use_connect = False @@ -574,6 +653,7 @@ class Rig: eb[ roll1_mch ].parent = None flip_bone( self.obj, roll1_mch ) + align_bone_x_axis(self.obj, roll1_mch, eb[org_bones[2]].x_axis) # Create 2nd roll mch, and two rock mch bones roll2_mch = get_bone_name( tmp_heel, 'mch', 'roll' ) @@ -598,6 +678,7 @@ class Rig: eb[ rock1_mch ].parent = None orient_bone( self, eb[ rock1_mch ], 'y', 1.0, reverse = True ) + align_bone_y_axis(self.obj, rock1_mch, ax) eb[ rock1_mch ].length = eb[ tmp_heel ].length / 2 rock2_mch = get_bone_name( tmp_heel, 'mch', 'rock' ) @@ -606,7 +687,8 @@ class Rig: eb[ rock2_mch ].use_connect = False eb[ rock2_mch ].parent = None - orient_bone( self, eb[ rock2_mch ], 'y', 1.0 ) + #orient_bone( self, eb[ rock2_mch ], 'y', 1.0 ) + align_bone_y_axis(self.obj, rock2_mch, ax) eb[ rock2_mch ].length = eb[ tmp_heel ].length / 2 # Parent rock and roll MCH bones @@ -694,6 +776,11 @@ class Rig: 'subtarget' : ctrl_root, }) + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': ctrl_root, + }) + if leg_parent: make_constraint( self, ctrl_socket, { 'constraint' : 'COPY_TRANSFORMS', @@ -701,6 +788,12 @@ class Rig: 'influence' : 0.0, }) + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': bones['ik']['mch_target'], + }) + + # Constrain mch target bone to the ik control and mch stretch make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', 'subtarget' : bones['ik']['mch_str'], @@ -727,19 +820,22 @@ class Rig: }) # 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 + pb_parent = pb[bones['main_parent']] + pb_parent.lock_location = True, True, True + pb_parent.lock_rotation = True, True, True + pb_parent.lock_scale = True, True, True + + pb_parent['IK_Stretch'] = 1.0 + prop = rna_idprop_ui_prop_get(pb_parent, 'IK_Stretch', 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 + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -747,12 +843,12 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - drv_modifier.mode = 'POLYNOMIAL' - drv_modifier.poly_order = 1 + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 @@ -760,9 +856,9 @@ class Rig: create_foot_widget(self.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 + 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(self.obj, heel, bone_transform_name=None) @@ -770,32 +866,31 @@ class Rig: bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones - if len( org_bones ) >= 4: + if len(org_bones) >= 4: # Create toes control bone - toes = get_bone_name( org_bones[3], 'ctrl' ) - toes = copy_bone( self.obj, org_bones[3], toes ) + toes = get_bone_name(org_bones[3], 'ctrl') + toes = copy_bone(self.obj, org_bones[3], toes) - eb[ toes ].use_connect = False - eb[ toes ].parent = eb[ org_bones[3] ] + eb[toes].use_connect = False + eb[toes].parent = eb[org_bones[3]] # Constrain toes def bones - make_constraint( self, bones['def'][-2], { - 'constraint' : 'DAMPED_TRACK', - 'subtarget' : toes + make_constraint(self, bones['def'][-2], { + 'constraint': 'DAMPED_TRACK', + 'subtarget': toes }) - make_constraint( self, bones['def'][-2], { - 'constraint' : 'STRETCH_TO', - 'subtarget' : toes + make_constraint(self, bones['def'][-2], { + 'constraint': 'STRETCH_TO', + 'subtarget': toes }) - - make_constraint( self, bones['def'][-1], { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : toes + make_constraint(self, bones['def'][-1], { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': toes }) # Find IK/FK switch property - pb = self.obj.pose.bones - prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' ) + pb = self.obj.pose.bones + prop = rna_idprop_ui_prop_get( pb[bones['fk']['ctrl'][-1]], 'IK/FK' ) # Modify rotation mode for ik and tweak controls pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY' @@ -804,8 +899,8 @@ class Rig: pb[b].rotation_mode = 'ZXY' # Add driver to limit scale constraint influence - b = org_bones[3] - drv = pb[b].constraints[-1].driver_add("influence").driver + b = org_bones[3] + drv = pb[b].constraints[-1].driver_add("influence").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -817,38 +912,130 @@ class Rig: drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - drv_modifier.mode = 'POLYNOMIAL' - drv_modifier.poly_order = 1 + 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(self.obj, toes, radius=0.4, head_tail=0.5) - bones['ik']['ctrl']['terminal'] += [ toes ] + bones['ik']['ctrl']['terminal'] += [toes] bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] if leg_parent: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_pole_socket, ctrl_root, ctrl_parent] else: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_pole_socket, ctrl_root] return bones def create_drivers(self, bones): - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones ctrl = pb[bones['ik']['mch_foot'][0]] + ctrl_pole = pb[bones['ik']['mch_foot'][1]] + + #owner = pb[bones['ik']['ctrl']['limb']] + owner = pb[bones['main_parent']] - props = [ "IK_follow", "root/parent" ] + props = ["IK_follow", "root/parent", "pole_vector", "pole_follow"] for prop in props: - if prop == 'IK_follow': - ctrl[prop] = True - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + if prop == 'pole_vector': + owner[prop] = False + pole_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + pole_prop["min"] = False + pole_prop["max"] = True + pole_prop["description"] = prop + mch_ik = pb[bones['ik']['mch_ik']] + + # ik target hide driver + pole_target = pb[bones['ik']['ctrl']['ik_target']] + drv = pole_target.bone.driver_add("hide").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 = \ + owner.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 + + # vis-pole hide driver + vispole = pb[bones['ik']['visuals']['vispole']] + drv = vispole.bone.driver_add("hide").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 = \ + owner.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 + + # arrow hide driver + # pole_target = pb[bones['ik']['ctrl']['limb']] + # drv = pole_target.bone.driver_add("hide").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 = \ + # owner.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] = 0.0 + # drv_modifier.coefficients[1] = 1.0 + + for cns in mch_ik.constraints: + if 'IK' in cns.type: + drv = cns.driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + if not cns.pole_subtarget: + drv_modifier.coefficients[0] = 0.0 + drv_modifier.coefficients[1] = 1 + else: + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'IK_follow': + + owner[prop] = True + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) rna_prop["min"] = False rna_prop["max"] = True rna_prop["description"] = prop @@ -861,7 +1048,7 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] @@ -871,7 +1058,7 @@ class Rig: drv_modifier.coefficients[1] = -1.0 if len(ctrl.constraints) > 1: - drv = ctrl.constraints[ 1 ].driver_add("mute").driver + drv = ctrl.constraints[1].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -879,7 +1066,7 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] @@ -888,33 +1075,7 @@ class Rig: drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 - elif len(ctrl.constraints) > 1: - ctrl[prop]=0.0 - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = 0.0 - rna_prop["max"] = 1.0 - rna_prop["soft_min"] = 0.0 - rna_prop["soft_max"] = 1.0 - rna_prop["description"] = prop - - # drv = ctrl.constraints[ 0 ].driver_add("influence").driver - # drv.type = 'AVERAGE' - # - # var = drv.variables.new() - # var.name = prop - # var.type = "SINGLE_PROP" - # var.targets[0].id = self.obj - # var.targets[0].data_path = \ - # ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - # - # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - # - # drv_modifier.mode = 'POLYNOMIAL' - # drv_modifier.poly_order = 1 - # drv_modifier.coefficients[0] = 1.0 - # drv_modifier.coefficients[1] = -1.0 - - drv = ctrl.constraints[ 1 ].driver_add("influence").driver + drv = ctrl_pole.constraints[0].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -922,42 +1083,109 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + if len(ctrl_pole.constraints) > 1: + drv = ctrl_pole.constraints[1].driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'root/parent': + if len(ctrl.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + elif prop == 'pole_follow': + if len(ctrl_pole.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl_pole.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' def generate(self): - bpy.ops.object.mode_set(mode ='EDIT') + 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 + 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'] - ) + mch_parent, main_parent = self.create_parent() + bones['parent'] = mch_parent + bones['main_parent'] = main_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['main_parent']) - bones = self.create_leg( bones ) - self.create_drivers( bones ) + bones = self.create_leg(bones) + self.create_drivers(bones) - controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] + controls = [bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] + + controls.append(bones['main_parent']) # Create UI controls_string = ", ".join(["'" + x + "'" for x in controls]) - script = create_script( bones, 'leg' ) - script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') + script = create_script(bones, 'leg') + script += extra_script % (controls_string, bones['main_parent'], 'IK_follow', 'pole_follow', 'root/parent', 'root/parent') - return [ script ] + return [script] def add_parameters(params): @@ -1060,29 +1288,6 @@ def parameters_ui(layout, params): row.prop(params, layer + "_layers", index=i, toggle=True, text="") -def get_future_names(bone): - - list=[] - - if '.L' in bone or '.R' in bone: - name = bone[:-2] - suffix = bone[-2:] - - list.append(org(name) + suffix) - list.append(make_mechanism_name(name) + 'ik_stretch' + suffix) - list.append(make_deformer_name(name) + suffix) - list.append(name + '_fk' + suffix) - list.append(name + '_tweak' + suffix) - - list.append(name + '_tweak' + suffix + '.001') - list.append(name + '_ik' + suffix) - - return list - - - return ['prova', 'prova2'] - - def create_sample(obj): # generated by rigify.utils.write_metarig bpy.ops.object.mode_set(mode='EDIT') @@ -1090,7 +1295,7 @@ def create_sample(obj): bones = {} - for _ in range(28): + for _ in range(29): arm.rigify_layers.add() arm.rigify_layers[13].name = 'Leg.L (IK)' @@ -1099,6 +1304,8 @@ def create_sample(obj): arm.rigify_layers[14].row = 11 arm.rigify_layers[15].name = 'Leg.L (Tweak)' arm.rigify_layers[15].row = 12 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 bone = arm.edit_bones.new('thigh.L') bone.head[:] = 0.0980, 0.0124, 1.0720 @@ -1138,7 +1345,7 @@ def create_sample(obj): bpy.ops.object.mode_set(mode='OBJECT') pbone = obj.pose.bones[bones['thigh.L']] - pbone.rigify_type = 'pitchipoy.limbs.super_limb' + pbone.rigify_type = 'limbs.super_limb' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False diff --git a/rigify/rigs/limbs/limb_utils.py b/rigify/rigs/limbs/limb_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..111a7d1c4e6bde6b64f6dd6bb20f7110f04d5934 --- /dev/null +++ b/rigify/rigs/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 constraint props to those that actually exist in the current + # type of constraint, then assign values to each + for p in [ k for k in constraint.keys() if k in dir(const) ]: + 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/rigs/pitchipoy/limbs/super_front_paw.py b/rigify/rigs/limbs/paw.py similarity index 66% rename from rigify/rigs/pitchipoy/limbs/super_front_paw.py rename to rigify/rigs/limbs/paw.py index 04e6280fbee2cd2bf2368177a77891d99798a13d..c01f2f0db828e94fd479d78e0a920a6e28274821 100644 --- a/rigify/rigs/pitchipoy/limbs/super_front_paw.py +++ b/rigify/rigs/limbs/paw.py @@ -1,45 +1,47 @@ -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 ..super_widgets import create_foot_widget, create_ballsocket_widget -from math import trunc - +import bpy +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, create_line_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 ..widgets import create_ikarrow_widget, create_gear_widget +from ..widgets import create_foot_widget, create_ballsocket_widget +from math import trunc, pi extra_script = """ controls = [%s] ctrl = '%s' if is_selected( controls ): + layout.prop( pose_bones[ ctrl ], '["%s"]') layout.prop( pose_bones[ ctrl ], '["%s"]') if '%s' in pose_bones[ctrl].keys(): layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) """ +IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class + # add_parameters and parameters_ui are unused for implementation classes + + class Rig: + def __init__(self, obj, bone_name, params): - """ Initialize torso rig and key rig properties """ - self.obj = obj - self.params = params + """ Initialize paw rig and key rig properties """ + self.obj = obj + self.params = params 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.segments = params.segments + self.bbones = params.bbones self.limb_type = params.limb_type - self.rot_axis = params.rotation_axis + self.rot_axis = params.rotation_axis # Assign values to tweak/FK layers props if opted by user if params.tweak_extra_layers: @@ -56,7 +58,7 @@ class Rig: org_bones = self.org_bones - bpy.ops.object.mode_set(mode ='EDIT') + bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones name = get_bone_name( strip_org( org_bones[0] ), 'mch', 'parent' ) @@ -69,6 +71,13 @@ class Rig: eb[ mch ].roll = 0.0 + # Add non-MCH main limb control + name = get_bone_name(strip_org(org_bones[0]), 'ctrl', 'parent') + main_parent = copy_bone(self.obj, org_bones[0], name) + eb[main_parent].length = eb[org_bones[0]].length / 4 + eb[main_parent].parent = eb[org_bones[0]] + eb[main_parent].roll = 0.0 + # Constraints make_constraint( self, mch, { 'constraint' : 'COPY_ROTATION', @@ -85,26 +94,31 @@ class Rig: name = 'FK_limb_follow' - pb[ mch ][ name ] = 0.0 - prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + # pb[ mch ][ name ] = 0.0 + # prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True ) + pb[main_parent][name] = 0.0 + prop = rna_idprop_ui_prop_get(pb[main_parent], name, create=True) - prop["min"] = 0.0 - prop["max"] = 1.0 - prop["soft_min"] = 0.0 - prop["soft_max"] = 1.0 + 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 = 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() + \ + var.targets[0].data_path = pb[main_parent].path_from_id() + \ '[' + '"' + name + '"' + ']' - return mch + size = pb[main_parent].bone.y_axis.length * 10 + create_gear_widget(self.obj, main_parent, size=size, bone_transform_name=None) + + return [mch, main_parent] def create_tweak(self): org_bones = self.org_bones @@ -118,14 +132,7 @@ class Rig: # Create and parent mch and ctrl tweaks for i,org in enumerate(org_bones): - - #if (self.limb_type == 'paw'): - # idx_stop = len(org_bones) - #else: - # idx_stop = len(org_bones) - 1 - if i < len(org_bones) - 1: - # if i < idx_stop: # Create segments if specified for j in range( self.segments ): # MCH @@ -180,10 +187,6 @@ class Rig: # Contraints - # last_name = eb[eb.keys().index(org_bones[-1])+1].name - # tweaks['mch'] += [last_name] - # tweaks['ctrl'] += [last_name] - for i,b in enumerate( tweaks['mch'] ): first = 0 middle = trunc( len( tweaks['mch'] ) / 3 ) @@ -210,7 +213,6 @@ class Rig: 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) @@ -228,9 +230,6 @@ class Rig: 'subtarget' : tweaks['ctrl'][ dt_target_idx ], }) - # tweaks['mch'].pop() - # tweaks['ctrl'].pop() - # Ctrl bones Locks and Widgets pb = self.obj.pose.bones for t in tweaks['ctrl']: @@ -244,33 +243,32 @@ class Rig: return tweaks - def create_def(self, tweaks ): + def create_def(self, tweaks): org_bones = self.org_bones bpy.ops.object.mode_set(mode ='EDIT') eb = self.obj.data.edit_bones def_bones = [] - for i,org in enumerate(org_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 ) + 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 + 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) + put_bone(self.obj, def_name, eb[ def_bones[-1] ].tail) - def_bones += [ def_name ] + 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 ) + 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 ): @@ -302,9 +300,9 @@ class Rig: 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[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_in = 0.0 self.obj.data.bones[ def_bones[-1] ].bbone_out = 0.0 @@ -350,21 +348,21 @@ class Rig: return def_bones - def create_ik(self, parent ): + def create_ik(self, parent): org_bones = self.org_bones - bpy.ops.object.mode_set(mode ='EDIT') + 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' ) + 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 ) + 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 + if org_bones.index(o) == len(org_bones) - 1: + eb[bone].length /= 4 # Create MCH Stretch mch_str = copy_bone( @@ -378,17 +376,71 @@ class Rig: # Parenting eb[ ctrl ].parent = eb[ parent ] eb[ mch_str ].parent = eb[ parent ] - eb[ mch_ik ].parent = eb[ ctrl ] + # Make standard pole target bone + pole_name = get_bone_name(org_bones[0], 'ctrl', 'ik_target') + pole_target = copy_bone(self.obj, org_bones[0], pole_name) + + lo_vector = eb[org_bones[1]].tail - eb[org_bones[1]].head + tot_vector = eb[org_bones[0]].head - eb[org_bones[1]].tail + tot_vector.normalize() + elbow_vector = lo_vector.dot(tot_vector)*tot_vector - lo_vector # elbow_vec as regression of lo on tot + elbow_vector.normalize() + elbow_vector *= (eb[org_bones[1]].tail - eb[org_bones[0]].head).length + z_vector = eb[org_bones[0]].z_axis + eb[org_bones[1]].z_axis + alfa = elbow_vector.angle(z_vector) + + if alfa > pi/2: + pole_angle = -pi/2 + else: + pole_angle = pi/2 + + eb[pole_target].head = eb[org_bones[0]].tail + elbow_vector + eb[pole_target].tail = eb[pole_target].head - elbow_vector/8 + eb[pole_target].roll = 0.0 + + # Make visual pole + vispole_name = 'VIS_' + get_bone_name(org_bones[0], 'ctrl', 'ik_pole') + vispole = copy_bone(self.obj, org_bones[1], vispole_name) + eb[vispole].tail = eb[vispole].head + Vector((0.0, 0.0, eb[org_bones[1]].length/10)) + eb[vispole].use_connect = False + eb[vispole].hide_select = True + eb[vispole].parent = None + + make_constraint(self, mch_ik, { + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) - make_constraint( self, mch_ik, { - 'constraint' : 'IK', - 'subtarget' : mch_target, - 'chain_count' : 2, + make_constraint(self, mch_ik, { # 2_nd IK for pole targeted chain + 'constraint': 'IK', + 'subtarget': mch_target, + 'chain_count': 2, + }) + + # VIS pole constraints + make_constraint(self, vispole, { + 'constraint': 'COPY_LOCATION', + 'name': 'copy_loc', + 'subtarget': org_bones[1], }) pb = self.obj.pose.bones + + make_constraint(self, vispole, { + 'constraint': 'STRETCH_TO', + 'name': 'stretch_to', + 'subtarget': pole_target, + 'volume': 'NO_VOLUME', + 'rest_length': pb[vispole].length + }) + + pb[mch_ik].constraints[-1].pole_target = self.obj + pb[mch_ik].constraints[-1].pole_subtarget = pole_target + pb[mch_ik].constraints[-1].pole_angle = pole_angle + pb[ mch_ik ].ik_stretch = 0.1 pb[ ctrl ].ik_stretch = 0.1 @@ -400,55 +452,58 @@ class Rig: # 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 + create_sphere_widget(self.obj, pole_target, bone_transform_name=None) + create_line_widget(self.obj, vispole) + + return {'ctrl': {'limb': ctrl, 'ik_target': pole_target}, + 'mch_ik': mch_ik, + 'mch_target': mch_target, + 'mch_str': mch_str, + 'visuals': {'vispole': vispole} } - def create_fk(self, parent ): + def create_fk(self, parent): org_bones = self.org_bones.copy() org_bones.pop() - bpy.ops.object.mode_set(mode ='EDIT') + 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 ) + 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' ) + self.obj, org_bones[-1], get_bone_name(o, 'mch', 'fk') ) - eb[ mch ].length /= 4 + 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 + 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' + 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 + pb[ctrls[2]].lock_location = True, True, True - create_limb_widget( self.obj, ctrls[0] ) - create_limb_widget( self.obj, ctrls[1] ) + 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) @@ -456,43 +511,43 @@ class Rig: if self.fk_layers: pb[c].bone.layers = self.fk_layers - return { 'ctrl' : ctrls, 'mch' : mch } + return {'ctrl': ctrls, 'mch': mch} - def org_parenting_and_switch(self, org, ik, fk, parent): - bpy.ops.object.mode_set(mode ='EDIT') + def org_parenting_and_switch(self, org_bones, 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): + for i, o in enumerate(org_bones): if i > 0: - eb[o].parent = eb[ org[i-1] ] - if i <= len(org)-1: + eb[o].parent = eb[org_bones[i-1]] + if i <= len(org_bones)-1: eb[o].use_connect = True - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones - pb_parent = pb[ parent ] + 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 + 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'] ] + iks = [ik['ctrl']['limb']] + iks += [ik[k] for k in ['mch_ik', 'mch_target']] - for o, i, f in zip( org, iks, fk ): + for o, i, f in zip(org_bones, iks, fk): make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : i + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': i }) - make_constraint( self, o, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : f + make_constraint(self, o, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': f }) # Add driver to relevant constraint @@ -504,10 +559,9 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - - def create_paw( self, bones ): + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' + def create_paw(self, bones): org_bones = list( [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) ) @@ -517,13 +571,15 @@ class Rig: bpy.ops.object.mode_set(mode='EDIT') eb = self.obj.data.edit_bones + pole_target = get_bone_name(org_bones[0], 'ctrl', 'ik_target') + # Create IK paw control - ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) - ctrl = copy_bone( self.obj, org_bones[2], ctrl ) + ctrl = get_bone_name(org_bones[2], 'ctrl', 'ik') + ctrl = copy_bone(self.obj, org_bones[2], ctrl) # clear parent (so that rigify will parent to root) - eb[ ctrl ].parent = None - eb[ ctrl ].use_connect = False + eb[ctrl].parent = None + eb[ctrl].use_connect = False # MCH for ik control ctrl_socket = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_socket')) @@ -531,6 +587,12 @@ class Rig: eb[ctrl_socket].parent = None eb[ctrl].parent = eb[ctrl_socket] + # MCH for pole ik control + ctrl_pole_socket = copy_bone(self.obj, org_bones[2], get_bone_name(org_bones[2], 'mch', 'pole_ik_socket')) + eb[ctrl_pole_socket].tail = eb[ctrl_pole_socket].head + 0.8 * (eb[ctrl_pole_socket].tail - eb[ctrl_pole_socket].head) + eb[ctrl_pole_socket].parent = None + eb[pole_target].parent = eb[ctrl_pole_socket] + ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) eb[ctrl_root].use_connect = False @@ -541,12 +603,15 @@ class Rig: ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent + if eb[org_bones[0]].parent_recursive: + eb[ctrl_parent].parent = eb[org_bones[0]].parent_recursive[-1] + else: + eb[ctrl_parent].parent = eb[org_bones[0]].parent else: paw_parent = None - # Create heel control bone - heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) + # Create heel ctrl bone + heel = get_bone_name(org_bones[2], 'ctrl', 'heel_ik') heel = copy_bone( self.obj, org_bones[2], heel ) # clear parent @@ -563,9 +628,9 @@ class Rig: eb[ bones['ik']['mch_target'] ].use_connect = False # Reset control position and orientation - l = eb[ ctrl ].length - orient_bone( self, eb[ ctrl ], 'y', reverse = True ) - eb[ ctrl ].length = l + l = eb[ctrl].length + orient_bone(self, eb[ctrl], 'y', reverse=True) + eb[ctrl].length = eb[org_bones[-1]].length # Set up constraints @@ -576,6 +641,11 @@ class Rig: 'subtarget' : ctrl_root, }) + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': ctrl_root, + }) + if paw_parent: make_constraint( self, ctrl_socket, { 'constraint' : 'COPY_TRANSFORMS', @@ -583,6 +653,11 @@ class Rig: 'influence' : 0.0, }) + make_constraint(self, ctrl_pole_socket, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': bones['ik']['mch_target'], + }) + # Constrain mch target bone to the ik control and mch stretch make_constraint( self, bones['ik']['mch_target'], { 'constraint' : 'COPY_LOCATION', @@ -609,21 +684,25 @@ class Rig: 'owner_space' : 'LOCAL' }) - # Create ik/fk switch property pb = self.obj.pose.bones - 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 + + # Create ik/fk switch property + pb_parent = pb[bones['main_parent']] + pb_parent.lock_location = True, True, True + pb_parent.lock_rotation = True, True, True + pb_parent.lock_scale = True, True, True + + pb_parent['IK_Stretch'] = 1.0 + prop = rna_idprop_ui_prop_get(pb_parent, 'IK_Stretch', 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 + b = bones['ik']['mch_str'] + drv = pb[b].constraints[-1].driver_add("influence").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -631,7 +710,7 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' + pb_parent.path_from_id() + '[' + '"' + prop.name + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] @@ -686,10 +765,16 @@ class Rig: 'head_tail' : 1 }) - # Find IK/FK switch property pb = self.obj.pose.bones - prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' ) + #prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' ) + prop = rna_idprop_ui_prop_get(pb[bones['fk']['ctrl'][-1]], 'IK/FK') + + # 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' # Add driver to limit scale constraint influence b = org_bones[3] @@ -718,26 +803,118 @@ class Rig: bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] if paw_parent: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_pole_socket, ctrl_root, ctrl_parent] else: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] + bones['ik']['mch_foot'] = [ctrl_socket, ctrl_pole_socket, ctrl_root] return bones def create_drivers(self, bones): - bpy.ops.object.mode_set(mode ='OBJECT') + bpy.ops.object.mode_set(mode='OBJECT') pb = self.obj.pose.bones ctrl = pb[bones['ik']['mch_foot'][0]] + ctrl_pole = pb[bones['ik']['mch_foot'][1]] - props = [ "IK_follow", "root/parent" ] + #owner = pb[bones['ik']['ctrl']['limb']] + owner = pb[bones['main_parent']] + + props = ["IK_follow", "root/parent", "pole_vector", "pole_follow"] for prop in props: - if prop == 'IK_follow': - ctrl[prop] = True - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) + if prop == 'pole_vector': + owner[prop] = False + pole_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + pole_prop["min"] = False + pole_prop["max"] = True + pole_prop["description"] = prop + mch_ik = pb[bones['ik']['mch_ik']] + + # ik target hide driver + pole_target = pb[bones['ik']['ctrl']['ik_target']] + drv = pole_target.bone.driver_add("hide").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 = \ + owner.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 + + # vis-pole hide driver + vispole = pb[bones['ik']['visuals']['vispole']] + drv = vispole.bone.driver_add("hide").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 = \ + owner.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 + + # arrow hide driver + # pole_target = pb[bones['ik']['ctrl']['limb']] + # drv = pole_target.bone.driver_add("hide").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 = \ + # owner.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] = 0.0 + # drv_modifier.coefficients[1] = 1.0 + + for cns in mch_ik.constraints: + if 'IK' in cns.type: + drv = cns.driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + if not cns.pole_subtarget: + drv_modifier.coefficients[0] = 0.0 + drv_modifier.coefficients[1] = 1 + else: + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'IK_follow': + + owner[prop] = True + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) rna_prop["min"] = False rna_prop["max"] = True rna_prop["description"] = prop @@ -750,7 +927,7 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] @@ -760,7 +937,7 @@ class Rig: drv_modifier.coefficients[1] = -1.0 if len(ctrl.constraints) > 1: - drv = ctrl.constraints[ 1 ].driver_add("mute").driver + drv = ctrl.constraints[1].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -768,7 +945,7 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] @@ -777,33 +954,7 @@ class Rig: drv_modifier.coefficients[0] = 1.0 drv_modifier.coefficients[1] = -1.0 - elif len(ctrl.constraints) > 1: - ctrl[prop]=0.0 - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = 0.0 - rna_prop["max"] = 1.0 - rna_prop["soft_min"] = 0.0 - rna_prop["soft_max"] = 1.0 - rna_prop["description"] = prop - - # drv = ctrl.constraints[ 0 ].driver_add("influence").driver - # drv.type = 'AVERAGE' - # - # var = drv.variables.new() - # var.name = prop - # var.type = "SINGLE_PROP" - # var.targets[0].id = self.obj - # var.targets[0].data_path = \ - # ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - # - # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - # - # drv_modifier.mode = 'POLYNOMIAL' - # drv_modifier.poly_order = 1 - # drv_modifier.coefficients[0] = 1.0 - # drv_modifier.coefficients[1] = -1.0 - - drv = ctrl.constraints[ 1 ].driver_add("influence").driver + drv = ctrl_pole.constraints[0].driver_add("mute").driver drv.type = 'AVERAGE' var = drv.variables.new() @@ -811,45 +962,112 @@ class Rig: var.type = "SINGLE_PROP" var.targets[0].id = self.obj var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' + owner.path_from_id() + '[' + '"' + prop + '"' + ']' - def generate( self ): - bpy.ops.object.mode_set(mode ='EDIT') + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + if len(ctrl_pole.constraints) > 1: + drv = ctrl_pole.constraints[1].driver_add("mute").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] + + drv_modifier.mode = 'POLYNOMIAL' + drv_modifier.poly_order = 1 + drv_modifier.coefficients[0] = 1.0 + drv_modifier.coefficients[1] = -1.0 + + elif prop == 'root/parent': + if len(ctrl.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + elif prop == 'pole_follow': + if len(ctrl_pole.constraints) > 1: + owner[prop] = 0.0 + rna_prop = rna_idprop_ui_prop_get(owner, prop, create=True) + rna_prop["min"] = 0.0 + rna_prop["max"] = 1.0 + rna_prop["soft_min"] = 0.0 + rna_prop["soft_max"] = 1.0 + rna_prop["description"] = prop + + drv = ctrl_pole.constraints[1].driver_add("influence").driver + drv.type = 'AVERAGE' + + var = drv.variables.new() + var.name = prop + var.type = "SINGLE_PROP" + var.targets[0].id = self.obj + var.targets[0].data_path = \ + owner.path_from_id() + '[' + '"' + prop + '"' + ']' + + 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 + 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'] - ) + mch_parent, main_parent = self.create_parent() + bones['parent'] = mch_parent + bones['main_parent'] = main_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['main_parent']) + + bones = self.create_paw(bones) + self.create_drivers(bones) - bones = self.create_paw( bones ) - self.create_drivers( bones ) + controls = [bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2]] - controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] + controls.append(bones['main_parent']) # Create UI controls_string = ", ".join(["'" + x + "'" for x in controls]) - script = create_script( bones, 'paw' ) - script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') + script = create_script(bones, 'paw') + script += extra_script % (controls_string, bones['main_parent'], 'IK_follow', 'pole_follow', 'root/parent','root/parent') - return [ script ] + return [script] -def add_parameters( params ): +def add_parameters(params): """ Add the parameters of this rig type to the RigifyParameters PropertyGroup """ @@ -967,7 +1185,7 @@ def create_sample(obj): bones = {} - for _ in range(28): + for _ in range(29): arm.rigify_layers.add() arm.rigify_layers[5].name = 'Paws' @@ -980,6 +1198,8 @@ def create_sample(obj): arm.rigify_layers[8].row = 8 arm.rigify_layers[9].name = 'Arm.L (Tweak)' arm.rigify_layers[9].row = 9 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 bone = arm.edit_bones.new('upper_arm.L') bone.head[:] = 0.0313, -0.1149, 0.2257 @@ -1095,7 +1315,7 @@ def create_sample(obj): bpy.ops.object.mode_set(mode='OBJECT') pbone = obj.pose.bones[bones['upper_arm.L']] - pbone.rigify_type = 'pitchipoy.limbs.super_limb' + pbone.rigify_type = 'limbs.super_limb' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1151,14 +1371,14 @@ def create_sample(obj): pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' pbone = obj.pose.bones[bones['f_palm.004.L']] - pbone.rigify_type = 'pitchipoy.super_palm' + pbone.rigify_type = 'limbs.super_palm' 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_palm.001.L']] - pbone.rigify_type = 'pitchipoy.super_palm' + pbone.rigify_type = 'limbs.super_palm' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1179,7 +1399,7 @@ def create_sample(obj): pbone.lock_scale = (False, False, False) pbone.rotation_mode = 'QUATERNION' pbone = obj.pose.bones[bones['f_pinky.001.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1190,7 +1410,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_index.001.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1201,7 +1421,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_middle.001.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False @@ -1212,7 +1432,7 @@ def create_sample(obj): except AttributeError: pass pbone = obj.pose.bones[bones['f_ring.001.L']] - pbone.rigify_type = 'pitchipoy.simple_tentacle' + pbone.rigify_type = 'limbs.simple_tentacle' pbone.lock_location = (False, False, False) pbone.lock_rotation = (False, False, False) pbone.lock_rotation_w = False diff --git a/rigify/rigs/limbs/rear_paw.py b/rigify/rigs/limbs/rear_paw.py new file mode 100644 index 0000000000000000000000000000000000000000..462143f65e95a9508caf165c4726ebb07033a3e3 --- /dev/null +++ b/rigify/rigs/limbs/rear_paw.py @@ -0,0 +1,319 @@ +import bpy + +from .paw import Rig as pawRig +from .paw import parameters_ui +from .paw import add_parameters + +IMPLEMENTATION = True # Include and set True if Rig is just an implementation for a wrapper class + # add_parameters and parameters_ui are unused for implementation classes + + +class Rig(pawRig): + + def __init__(self, obj, bone_name, params): + super(Rig, self).__init__(obj, bone_name, params) + + +def create_sample(obj): + # generated by rigify.utils.write_metarig + bpy.ops.object.mode_set(mode='EDIT') + arm = obj.data + + bones = {} + + for _ in range(29): + arm.rigify_layers.add() + + arm.rigify_layers[5].name = 'Paws' + arm.rigify_layers[5].row = 5 + arm.rigify_layers[6].name = 'Paws (Tweak)' + arm.rigify_layers[6].row = 6 + arm.rigify_layers[13].name = 'Leg.L (IK)' + arm.rigify_layers[13].row = 7 + arm.rigify_layers[14].name = 'Leg.L (FK)' + arm.rigify_layers[14].row = 8 + arm.rigify_layers[15].name = 'Leg.L (Tweak)' + arm.rigify_layers[15].row = 9 + arm.rigify_layers[28].name = "Root" + arm.rigify_layers[28].row = 14 + + bone = arm.edit_bones.new('thigh.L') + bone.head[:] = 0.0291, 0.1181, 0.2460 + bone.tail[:] = 0.0293, 0.1107, 0.1682 + bone.roll = 3.1383 + bone.use_connect = False + bones['thigh.L'] = bone.name + bone = arm.edit_bones.new('shin.L') + bone.head[:] = 0.0293, 0.1107, 0.1682 + bone.tail[:] = 0.0293, 0.1684, 0.1073 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['thigh.L']] + bones['shin.L'] = bone.name + bone = arm.edit_bones.new('foot.L') + bone.head[:] = 0.0293, 0.1684, 0.1073 + bone.tail[:] = 0.0293, 0.1530, 0.0167 + bone.roll = 3.1416 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['shin.L']] + bones['foot.L'] = bone.name + bone = arm.edit_bones.new('r_toe.L') + bone.head[:] = 0.0293, 0.1530, 0.0167 + bone.tail[:] = 0.0293, 0.1224, 0.0167 + bone.roll = 0.0000 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['foot.L']] + bones['r_toe.L'] = bone.name + bone = arm.edit_bones.new('r_palm.001.L') + bone.head[:] = 0.0220, 0.1457, 0.0123 + bone.tail[:] = 0.0215, 0.1401, 0.0123 + bone.roll = 0.0014 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.001.L'] = bone.name + bone = arm.edit_bones.new('r_palm.002.L') + bone.head[:] = 0.0297, 0.1458, 0.0123 + bone.tail[:] = 0.0311, 0.1393, 0.0123 + bone.roll = -0.0005 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.002.L'] = bone.name + bone = arm.edit_bones.new('r_palm.003.L') + bone.head[:] = 0.0363, 0.1473, 0.0123 + bone.tail[:] = 0.0376, 0.1407, 0.0123 + bone.roll = 0.0000 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.003.L'] = bone.name + bone = arm.edit_bones.new('r_palm.004.L') + bone.head[:] = 0.0449, 0.1501, 0.0123 + bone.tail[:] = 0.0466, 0.1479, 0.0123 + bone.roll = -0.0004 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_toe.L']] + bones['r_palm.004.L'] = bone.name + bone = arm.edit_bones.new('r_index.001.L') + bone.head[:] = 0.0215, 0.1367, 0.0087 + bone.tail[:] = 0.0217, 0.1325, 0.0070 + bone.roll = -0.3427 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.001.L']] + bones['r_index.001.L'] = bone.name + bone = arm.edit_bones.new('r_middle.001.L') + bone.head[:] = 0.0311, 0.1358, 0.0117 + bone.tail[:] = 0.0324, 0.1297, 0.0092 + bone.roll = -1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.002.L']] + bones['r_middle.001.L'] = bone.name + bone = arm.edit_bones.new('r_ring.001.L') + bone.head[:] = 0.0376, 0.1372, 0.0117 + bone.tail[:] = 0.0389, 0.1311, 0.0092 + bone.roll = -1.0029 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.003.L']] + bones['r_ring.001.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.001.L') + bone.head[:] = 0.0466, 0.1444, 0.0083 + bone.tail[:] = 0.0476, 0.1412, 0.0074 + bone.roll = -1.7551 + bone.use_connect = False + bone.parent = arm.edit_bones[bones['r_palm.004.L']] + bones['r_pinky.001.L'] = bone.name + bone = arm.edit_bones.new('r_index.002.L') + bone.head[:] = 0.0217, 0.1325, 0.0070 + bone.tail[:] = 0.0221, 0.1271, 0.0038 + bone.roll = -0.2465 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_index.001.L']] + bones['r_index.002.L'] = bone.name + bone = arm.edit_bones.new('r_middle.002.L') + bone.head[:] = 0.0324, 0.1297, 0.0092 + bone.tail[:] = 0.0343, 0.1210, 0.0039 + bone.roll = -0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_middle.001.L']] + bones['r_middle.002.L'] = bone.name + bone = arm.edit_bones.new('r_ring.002.L') + bone.head[:] = 0.0389, 0.1311, 0.0092 + bone.tail[:] = 0.0407, 0.1229, 0.0042 + bone.roll = -0.7479 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_ring.001.L']] + bones['r_ring.002.L'] = bone.name + bone = arm.edit_bones.new('r_pinky.002.L') + bone.head[:] = 0.0476, 0.1412, 0.0074 + bone.tail[:] = 0.0494, 0.1351, 0.0032 + bone.roll = -0.8965 + bone.use_connect = True + bone.parent = arm.edit_bones[bones['r_pinky.001.L']] + bones['r_pinky.002.L'] = bone.name + + bpy.ops.object.mode_set(mode='OBJECT') + pbone = obj.pose.bones[bones['thigh.L']] + pbone.rigify_type = '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.limb_type = "paw" + except AttributeError: + pass + try: + pbone.rigify_parameters.fk_layers = [False, False, False, False, False, 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] + except AttributeError: + pass + try: + pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, 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] + except AttributeError: + pass + try: + pbone.rigify_parameters.segments = 2 + except AttributeError: + pass + pbone = obj.pose.bones[bones['shin.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['foot.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['r_toe.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['r_palm.001.L']] + pbone.rigify_type = 'limbs.super_palm' + 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['r_palm.002.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['r_palm.003.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['r_palm.004.L']] + pbone.rigify_type = 'limbs.super_palm' + 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['r_index.001.L']] + pbone.rigify_type = 'limbs.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.tweak_layers = [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, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_middle.001.L']] + pbone.rigify_type = 'limbs.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.tweak_layers = [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, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_ring.001.L']] + pbone.rigify_type = 'limbs.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.tweak_layers = [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, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_pinky.001.L']] + pbone.rigify_type = 'limbs.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.tweak_layers = [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, False, False] + except AttributeError: + pass + pbone = obj.pose.bones[bones['r_index.002.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['r_middle.002.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['r_ring.002.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['r_pinky.002.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 + + for eb in arm.edit_bones: + if ('thigh' in eb.name) or ('shin' in eb.name) or ('foot' in eb.name) or ('toe' in eb.name): + eb.layers = (False, False, False, False, 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) + else: + eb.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) + arm.layers = (False, False, False, False, False, True, 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) + + +if __name__ == "__main__": + create_sample(bpy.context.active_object) diff --git a/rigify/rigs/limbs/simple_tentacle.py b/rigify/rigs/limbs/simple_tentacle.py new file mode 100644 index 0000000000000000000000000000000000000000..d7457c58017f1f34f5baea0f5babc3444ea30e08 --- /dev/null +++ b/rigify/rigs/limbs/simple_tentacle.py @@ -0,0 +1,345 @@ +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_rotation_axes = params.copy_rotation_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 on bone: %s" % (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_rotation_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_rotation_axes = bpy.props.BoolVectorProperty( + size=3, + description="Automation axes", + 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_rotation_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 = 'limbs.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/rigs/limbs/super_finger.py b/rigify/rigs/limbs/super_finger.py new file mode 100644 index 0000000000000000000000000000000000000000..60645372eea44c0cd68906ddfeec44356691da56 --- /dev/null +++ b/rigify/rigs/limbs/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 = 'limbs.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/rigs/limbs/super_limb.py b/rigify/rigs/limbs/super_limb.py new file mode 100644 index 0000000000000000000000000000000000000000..8400ea248119f194da93aab552fa9de87dafb54c --- /dev/null +++ b/rigify/rigs/limbs/super_limb.py @@ -0,0 +1,243 @@ +import bpy + +from .arm import Rig as armRig +from .leg import Rig as legRig +from .paw import Rig as pawRig + + +class Rig: + + def __init__(self, obj, bone_name, params): + """ Initialize super_limb rig wrapper class """ + self.obj = obj + self.params = params + + if params.limb_type == 'arm': + self.limb = armRig(obj, bone_name, params) + elif params.limb_type == 'leg': + self.limb = legRig(obj, bone_name, params) + elif params.limb_type == 'paw': + self.limb = pawRig(obj, bone_name, params) + + def generate(self): + + return self.limb.generate() + + +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 = '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/rigs/limbs/super_palm.py b/rigify/rigs/limbs/super_palm.py new file mode 100644 index 0000000000000000000000000000000000000000..efcb5681652eb970d782056efa28e303590b3aca --- /dev/null +++ b/rigify/rigs/limbs/super_palm.py @@ -0,0 +1,328 @@ +# ##### 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 ##### + +# <pep8 compliant> + +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 + if def_parent in eb.keys(): + parent_to = def_parent + else: + parent_to = org_parent + for o in self.org_bones: + eb[o].parent = eb[parent_to] + eb[ctrl].parent = eb[parent_to] + + # 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 = parent_to + 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/rigs/limbs/ui.py b/rigify/rigs/limbs/ui.py new file mode 100644 index 0000000000000000000000000000000000000000..948b57199337e2fce45d961c740e0444c5e5b86a --- /dev/null +++ b/rigify/rigs/limbs/ui.py @@ -0,0 +1,166 @@ +script_arm = """ +controls = [%s] +tweaks = [%s] +ik_ctrl = [%s] +fk_ctrl = '%s' +parent = '%s' +hand_fk = '%s' +pole = '%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 = pole + props.main_parent = parent + + +# 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 and pole_vector on IK Control bone +if is_selected( ik_ctrl ) or is_selected(parent): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + layout.prop( pose_bones[ parent ], '["%s"]') + +# FK limb follow +if is_selected( fk_ctrl ) or is_selected(parent): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) +""" + +script_leg = """ +controls = [%s] +tweaks = [%s] +ik_ctrl = [%s] +fk_ctrl = '%s' +parent = '%s' +foot_fk = '%s' +pole = '%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 = pole + props.footroll = controls[5] + props.mfoot_ik = ik_ctrl[2] + props.main_parent = parent + +# 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 and pole_vector on IK Control bone +if is_selected( ik_ctrl ) or is_selected(parent): + layout.prop( pose_bones[ parent ], '["%s"]', slider = True ) + layout.prop( pose_bones[ parent ], '["%s"]') + +# FK limb follow +if is_selected( fk_ctrl ) or is_selected(parent): + 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 += [bones['main_parent']] + + 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 'ik_target' in bones['ik']['ctrl'].keys(): + pole = bones['ik']['ctrl']['ik_target'] + else: + pole = '' + + if limb_type == 'arm': + return script_arm % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['main_parent'], + bones['fk']['ctrl'][-1], + pole, + 'IK/FK', + 'rubber_tweak', + 'IK_Stretch', + 'pole_vector', + 'FK_limb_follow' + ) + + elif limb_type == 'leg': + return script_leg % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['main_parent'], + bones['fk']['ctrl'][-1], + pole, + 'IK/FK', + 'rubber_tweak', + 'IK_Stretch', + 'pole_vector', + 'FK_limb_follow' + ) + + elif limb_type == 'paw': + return script_leg % ( + controls_string, + tweaks_string, + ik_ctrl_string, + bones['fk']['ctrl'][0], + bones['main_parent'], + bones['fk']['ctrl'][-1], + pole, + 'IK/FK', + 'rubber_tweak', + 'IK_Stretch', + 'pole_vector', + 'FK_limb_follow' + ) diff --git a/rigify/rigs/pitchipoy/limbs/super_rear_paw.py b/rigify/rigs/pitchipoy/limbs/super_rear_paw.py deleted file mode 100644 index c31346c93d2ff888808615871bd568e21877b81f..0000000000000000000000000000000000000000 --- a/rigify/rigs/pitchipoy/limbs/super_rear_paw.py +++ /dev/null @@ -1,1261 +0,0 @@ -import bpy, re -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 ..super_widgets import create_foot_widget, create_ballsocket_widget -from math import trunc - - -extra_script = """ -controls = [%s] -ctrl = '%s' - -if is_selected( controls ): - layout.prop( pose_bones[ ctrl ], '["%s"]') - if '%s' in pose_bones[ctrl].keys(): - layout.prop( pose_bones[ ctrl ], '["%s"]', slider = True ) -""" - - -class Rig: - def __init__(self, obj, bone_name, params): - """ Initialize torso rig and key rig properties """ - self.obj = obj - self.params = params - - 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 (self.limb_type == 'paw'): - # idx_stop = len(org_bones) - #else: - # idx_stop = len(org_bones) - 1 - - if i < len(org_bones) - 1: - # if i < idx_stop: - # 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 - - # last_name = eb[eb.keys().index(org_bones[-1])+1].name - # tweaks['mch'] += [last_name] - # tweaks['ctrl'] += [last_name] - - 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 ], - }) - - # tweaks['mch'].pop() - # tweaks['ctrl'].pop() - - # 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' ) - ) - - 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() - - - 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_paw( self, bones ): - - org_bones = list( - [self.org_bones[0]] + connected_children_names(self.obj, self.org_bones[0]) - ) - - bones['ik']['ctrl']['terminal'] = [] - - bpy.ops.object.mode_set(mode='EDIT') - eb = self.obj.data.edit_bones - - # Create IK paw control - ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' ) - ctrl = copy_bone( self.obj, org_bones[2], ctrl ) - - # clear parent (so that rigify will parent to root) - eb[ ctrl ].parent = None - eb[ ctrl ].use_connect = False - - # MCH for ik control - ctrl_socket = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_socket')) - eb[ctrl_socket].tail = eb[ctrl_socket].head + 0.8*(eb[ctrl_socket].tail-eb[ctrl_socket].head) - eb[ctrl_socket].parent = None - eb[ctrl].parent = eb[ctrl_socket] - - ctrl_root = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_root')) - eb[ctrl_root].tail = eb[ctrl_root].head + 0.7*(eb[ctrl_root].tail-eb[ctrl_root].head) - eb[ctrl_root].use_connect = False - eb[ctrl_root].parent = eb['root'] - - if eb[org_bones[0]].parent: - paw_parent = eb[org_bones[0]].parent - ctrl_parent = copy_bone(self.obj, org_bones[2], get_bone_name( org_bones[2], 'mch', 'ik_parent')) - eb[ctrl_parent].tail = eb[ctrl_parent].head + 0.6*(eb[ctrl_parent].tail-eb[ctrl_parent].head) - eb[ctrl_parent].use_connect = False - eb[ctrl_parent].parent = eb[org_bones[0]].parent - else: - paw_parent = None - - # Create heel control bone - heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' ) - heel = copy_bone( self.obj, org_bones[2], heel ) - - # clear parent - eb[ heel ].parent = None - eb[ heel ].use_connect = False - - # Parent - eb[ heel ].parent = eb[ ctrl ] - eb[ heel ].use_connect = False - - flip_bone( self.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( self, eb[ ctrl ], 'y', reverse = True ) - eb[ ctrl ].length = l - - # Set up constraints - - # Constrain ik ctrl to root / parent - - make_constraint( self, ctrl_socket, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : ctrl_root, - }) - - if paw_parent: - make_constraint( self, ctrl_socket, { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : ctrl_parent, - 'influence' : 0.0, - }) - - # Constrain mch target bone to the ik control and mch stretch - make_constraint( self, bones['ik']['mch_target'], { - 'constraint' : 'COPY_LOCATION', - 'subtarget' : bones['ik']['mch_str'], - 'head_tail' : 1.0 - }) - - # Constrain mch ik stretch bone to the ik control - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'DAMPED_TRACK', - 'subtarget' : heel, - 'head_tail' : 1.0 - }) - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'STRETCH_TO', - 'subtarget' : heel, - 'head_tail' : 1.0 - }) - make_constraint( self, bones['ik']['mch_str'], { - 'constraint' : 'LIMIT_SCALE', - 'use_min_y' : True, - 'use_max_y' : True, - 'max_y' : 1.05, - 'owner_space' : 'LOCAL' - }) - - # Create ik/fk switch property - pb = self.obj.pose.bones - 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 = self.obj - var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - - 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 - - # Create paw widget - create_foot_widget(self.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(self.obj, heel, bone_transform_name=None) - - bpy.ops.object.mode_set(mode='EDIT') - eb = self.obj.data.edit_bones - - if len( org_bones ) >= 4: - # Create toes control bone - toes = get_bone_name( org_bones[3], 'ctrl' ) - toes = copy_bone( self.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( self.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( self, org_bones[3], { - 'constraint' : 'COPY_TRANSFORMS', - 'subtarget' : toes_mch - }) - - make_constraint( self, bones['def'][-1], { - 'constraint' : 'DAMPED_TRACK', - 'subtarget' : toes, - 'head_tail' : 1 - }) - make_constraint( self, bones['def'][-1], { - 'constraint' : 'STRETCH_TO', - 'subtarget' : toes, - 'head_tail' : 1 - }) - - - # Find IK/FK switch property - pb = self.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 = self.obj - var.targets[0].data_path = \ - pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']' - - 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 - - # Create toe circle widget - create_circle_widget(self.obj, toes, radius=0.4, head_tail=0.5) - - bones['ik']['ctrl']['terminal'] += [ toes ] - - bones['ik']['ctrl']['terminal'] += [ heel, ctrl ] - - if paw_parent: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root, ctrl_parent] - else: - bones['ik']['mch_foot'] = [ctrl_socket, ctrl_root] - - return bones - - def create_drivers(self, bones): - - bpy.ops.object.mode_set(mode ='OBJECT') - pb = self.obj.pose.bones - - ctrl = pb[bones['ik']['mch_foot'][0]] - - props = [ "IK_follow", "root/parent" ] - - for prop in props: - if prop == 'IK_follow': - - ctrl[prop] = True - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = False - rna_prop["max"] = True - rna_prop["description"] = prop - - drv = ctrl.constraints[ 0 ].driver_add("mute").driver - drv.type = 'AVERAGE' - - var = drv.variables.new() - var.name = prop - var.type = "SINGLE_PROP" - var.targets[0].id = self.obj - var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - - drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - - drv_modifier.mode = 'POLYNOMIAL' - drv_modifier.poly_order = 1 - drv_modifier.coefficients[0] = 1.0 - drv_modifier.coefficients[1] = -1.0 - - if len(ctrl.constraints) > 1: - drv = ctrl.constraints[ 1 ].driver_add("mute").driver - drv.type = 'AVERAGE' - - var = drv.variables.new() - var.name = prop - var.type = "SINGLE_PROP" - var.targets[0].id = self.obj - var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - - drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - - drv_modifier.mode = 'POLYNOMIAL' - drv_modifier.poly_order = 1 - drv_modifier.coefficients[0] = 1.0 - drv_modifier.coefficients[1] = -1.0 - - elif len(ctrl.constraints) > 1: - ctrl[prop]=0.0 - rna_prop = rna_idprop_ui_prop_get( ctrl, prop, create=True ) - rna_prop["min"] = 0.0 - rna_prop["max"] = 1.0 - rna_prop["soft_min"] = 0.0 - rna_prop["soft_max"] = 1.0 - rna_prop["description"] = prop - - # drv = ctrl.constraints[ 0 ].driver_add("influence").driver - # drv.type = 'AVERAGE' - # - # var = drv.variables.new() - # var.name = prop - # var.type = "SINGLE_PROP" - # var.targets[0].id = self.obj - # var.targets[0].data_path = \ - # ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - # - # drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0] - # - # drv_modifier.mode = 'POLYNOMIAL' - # drv_modifier.poly_order = 1 - # drv_modifier.coefficients[0] = 1.0 - # drv_modifier.coefficients[1] = -1.0 - - drv = ctrl.constraints[ 1 ].driver_add("influence").driver - drv.type = 'AVERAGE' - - var = drv.variables.new() - var.name = prop - var.type = "SINGLE_PROP" - var.targets[0].id = self.obj - var.targets[0].data_path = \ - ctrl.path_from_id() + '['+ '"' + prop + '"' + ']' - - def generate(self): - bpy.ops.object.mode_set(mode ='EDIT') - eb = self.obj.data.edit_bones - - # 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_paw( bones ) - self.create_drivers( bones ) - - controls = [ bones['ik']['ctrl']['limb'], bones['ik']['ctrl']['terminal'][-1], bones['ik']['ctrl']['terminal'][-2] ] - - # Create UI - controls_string = ", ".join(["'" + x + "'" for x in controls]) - - script = create_script( bones, 'paw' ) - script += extra_script % (controls_string, bones['ik']['mch_foot'][0], 'IK_follow', 'root/parent','root/parent') - - return [ script ] - - -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 = 'paw' - # ) - - 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 = {} - - for _ in range(28): - arm.rigify_layers.add() - - arm.rigify_layers[5].name = 'Paws' - arm.rigify_layers[5].row = 5 - arm.rigify_layers[6].name = 'Paws (Tweak)' - arm.rigify_layers[6].row = 6 - arm.rigify_layers[13].name = 'Leg.L (IK)' - arm.rigify_layers[13].row = 7 - arm.rigify_layers[14].name = 'Leg.L (FK)' - arm.rigify_layers[14].row = 8 - arm.rigify_layers[15].name = 'Leg.L (Tweak)' - arm.rigify_layers[15].row = 9 - - bone = arm.edit_bones.new('thigh.L') - bone.head[:] = 0.0291, 0.1181, 0.2460 - bone.tail[:] = 0.0293, 0.1107, 0.1682 - bone.roll = 3.1383 - bone.use_connect = False - bones['thigh.L'] = bone.name - bone = arm.edit_bones.new('shin.L') - bone.head[:] = 0.0293, 0.1107, 0.1682 - bone.tail[:] = 0.0293, 0.1684, 0.1073 - bone.roll = 3.1416 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['thigh.L']] - bones['shin.L'] = bone.name - bone = arm.edit_bones.new('foot.L') - bone.head[:] = 0.0293, 0.1684, 0.1073 - bone.tail[:] = 0.0293, 0.1530, 0.0167 - bone.roll = 3.1416 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['shin.L']] - bones['foot.L'] = bone.name - bone = arm.edit_bones.new('r_toe.L') - bone.head[:] = 0.0293, 0.1530, 0.0167 - bone.tail[:] = 0.0293, 0.1224, 0.0167 - bone.roll = 0.0000 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['foot.L']] - bones['r_toe.L'] = bone.name - bone = arm.edit_bones.new('r_palm.001.L') - bone.head[:] = 0.0220, 0.1457, 0.0123 - bone.tail[:] = 0.0215, 0.1401, 0.0123 - bone.roll = 0.0014 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_toe.L']] - bones['r_palm.001.L'] = bone.name - bone = arm.edit_bones.new('r_palm.002.L') - bone.head[:] = 0.0297, 0.1458, 0.0123 - bone.tail[:] = 0.0311, 0.1393, 0.0123 - bone.roll = -0.0005 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_toe.L']] - bones['r_palm.002.L'] = bone.name - bone = arm.edit_bones.new('r_palm.003.L') - bone.head[:] = 0.0363, 0.1473, 0.0123 - bone.tail[:] = 0.0376, 0.1407, 0.0123 - bone.roll = 0.0000 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_toe.L']] - bones['r_palm.003.L'] = bone.name - bone = arm.edit_bones.new('r_palm.004.L') - bone.head[:] = 0.0449, 0.1501, 0.0123 - bone.tail[:] = 0.0466, 0.1479, 0.0123 - bone.roll = -0.0004 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_toe.L']] - bones['r_palm.004.L'] = bone.name - bone = arm.edit_bones.new('r_index.001.L') - bone.head[:] = 0.0215, 0.1367, 0.0087 - bone.tail[:] = 0.0217, 0.1325, 0.0070 - bone.roll = -0.3427 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_palm.001.L']] - bones['r_index.001.L'] = bone.name - bone = arm.edit_bones.new('r_middle.001.L') - bone.head[:] = 0.0311, 0.1358, 0.0117 - bone.tail[:] = 0.0324, 0.1297, 0.0092 - bone.roll = -1.0029 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_palm.002.L']] - bones['r_middle.001.L'] = bone.name - bone = arm.edit_bones.new('r_ring.001.L') - bone.head[:] = 0.0376, 0.1372, 0.0117 - bone.tail[:] = 0.0389, 0.1311, 0.0092 - bone.roll = -1.0029 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_palm.003.L']] - bones['r_ring.001.L'] = bone.name - bone = arm.edit_bones.new('r_pinky.001.L') - bone.head[:] = 0.0466, 0.1444, 0.0083 - bone.tail[:] = 0.0476, 0.1412, 0.0074 - bone.roll = -1.7551 - bone.use_connect = False - bone.parent = arm.edit_bones[bones['r_palm.004.L']] - bones['r_pinky.001.L'] = bone.name - bone = arm.edit_bones.new('r_index.002.L') - bone.head[:] = 0.0217, 0.1325, 0.0070 - bone.tail[:] = 0.0221, 0.1271, 0.0038 - bone.roll = -0.2465 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['r_index.001.L']] - bones['r_index.002.L'] = bone.name - bone = arm.edit_bones.new('r_middle.002.L') - bone.head[:] = 0.0324, 0.1297, 0.0092 - bone.tail[:] = 0.0343, 0.1210, 0.0039 - bone.roll = -0.7479 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['r_middle.001.L']] - bones['r_middle.002.L'] = bone.name - bone = arm.edit_bones.new('r_ring.002.L') - bone.head[:] = 0.0389, 0.1311, 0.0092 - bone.tail[:] = 0.0407, 0.1229, 0.0042 - bone.roll = -0.7479 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['r_ring.001.L']] - bones['r_ring.002.L'] = bone.name - bone = arm.edit_bones.new('r_pinky.002.L') - bone.head[:] = 0.0476, 0.1412, 0.0074 - bone.tail[:] = 0.0494, 0.1351, 0.0032 - bone.roll = -0.8965 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['r_pinky.001.L']] - bones['r_pinky.002.L'] = bone.name - - bpy.ops.object.mode_set(mode='OBJECT') - pbone = obj.pose.bones[bones['thigh.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.limb_type = "paw" - except AttributeError: - pass - try: - pbone.rigify_parameters.fk_layers = [False, False, False, False, False, 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] - except AttributeError: - pass - try: - pbone.rigify_parameters.tweak_layers = [False, False, False, False, False, False, 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] - except AttributeError: - pass - try: - pbone.rigify_parameters.segments = 2 - except AttributeError: - pass - pbone = obj.pose.bones[bones['shin.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['foot.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['r_toe.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['r_palm.001.L']] - pbone.rigify_type = 'pitchipoy.super_palm' - 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['r_palm.002.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['r_palm.003.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['r_palm.004.L']] - pbone.rigify_type = 'pitchipoy.super_palm' - 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['r_index.001.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.tweak_layers = [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, False, False] - except AttributeError: - pass - pbone = obj.pose.bones[bones['r_middle.001.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.tweak_layers = [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, False, False] - except AttributeError: - pass - pbone = obj.pose.bones[bones['r_ring.001.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.tweak_layers = [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, False, False] - except AttributeError: - pass - pbone = obj.pose.bones[bones['r_pinky.001.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.tweak_layers = [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, False, False] - except AttributeError: - pass - pbone = obj.pose.bones[bones['r_index.002.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['r_middle.002.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['r_ring.002.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['r_pinky.002.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 - - for eb in arm.edit_bones: - if ('thigh' in eb.name) or ('shin' in eb.name) or ('foot' in eb.name) or ('toe' in eb.name): - eb.layers = (False, False, False, False, 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) - else: - eb.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) - arm.layers = (False, False, False, False, False, True, 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) - - -if __name__ == "__main__": - create_sample(bpy.context.active_object) \ No newline at end of file diff --git a/rigify/rigs/spines/__init__.py b/rigify/rigs/spines/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/rigify/rigs/spines/super_spine.py b/rigify/rigs/spines/super_spine.py new file mode 100644 index 0000000000000000000000000000000000000000..832a506a211930eaad14475f6714aa4fe3e0aa78 --- /dev/null +++ b/rigify/rigs/spines/super_spine.py @@ -0,0 +1,1249 @@ +import bpy +from mathutils import Vector +from ...utils import copy_bone, flip_bone, put_bone, org, align_bone_y_axis, align_bone_x_axis, align_bone_z_axis +from ...utils import strip_org, make_deformer_name, connected_children_names +from ...utils import create_circle_widget, create_sphere_widget, create_widget +from ..widgets import create_ballsocket_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 ): + if hasattr(pose_bones[torso],'["%s"]'): + layout.prop( pose_bones[ torso ], '["%s"]', slider = True ) + if hasattr(pose_bones[torso],'["%s"]'): + layout.prop( pose_bones[ torso ], '["%s"]', slider = True ) + if hasattr(pose_bones[torso],'["%s"]'): + 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]) + self.copy_rotation_axes = params.copy_rotation_axes + self.use_head = params.use_head + self.use_tail = params.use_tail + + # Check if user provided the pivot position + if params.pivot_pos: + self.pivot_pos = params.pivot_pos + 1 + else: + raise MetarigError( + "RIGIFY ERROR: please specify pivot bone position" + ) + + # Check if neck is lower than pivot + if self.use_head and params.neck_pos <= params.pivot_pos and params.neck_pos != 0: + raise MetarigError( + "RIGIFY ERROR: Neck cannot be below or the same as pivot. (use 0 for no neck)" + ) + else: + self.neck_pos = params.neck_pos + + if not self.use_head: + self.neck_pos = len(self.org_bones) + + if self.use_tail and self.pivot_pos - 2 > 0: + 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 bones for rig + min_bone_number = 3 + if self.use_head: + min_bone_number += 1 + if self.use_tail: + min_bone_number += 2 + + if len(self.org_bones) < min_bone_number: + raise MetarigError( + "RIGIFY ERROR: invalid rig structure on %s" % (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 == 0 or self.neck_pos > self.pivot_pos): + + neck_index = self.neck_pos - 1 + pivot_index = self.pivot_pos - 1 + + tail_index = 0 + if self.use_tail and self.tail_pos > 1: # 2 bones for the tail at least + tail_index = self.tail_pos - 1 + + if self.use_head: + neck_bones = self.org_bones[neck_index::] + upper_torso_bones = self.org_bones[pivot_index :neck_index] + else: + neck_bones = [] + upper_torso_bones = self.org_bones[pivot_index ::] + + tail_bones = [] + if tail_index: + lower_torso_bones = self.org_bones[tail_index + 1:pivot_index ] + tail_bones = self.org_bones[:tail_index+1] + else: + lower_torso_bones = self.org_bones[:pivot_index ] + + torso_bones = upper_torso_bones + lower_torso_bones + eb = self.obj.data.edit_bones + self.spine_length = sum([eb[b].length for b in torso_bones]) + + 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 * 0.6) + + # 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 self.use_tail and self.tail_pos > 0: + # pivot_loc = eb[org_bones[pivot-1]].head + if self.use_tail and self.tail_pos > 0: + first_torso_bone = self.tail_pos + pivot_loc = (eb[org_bones[first_torso_bone]].head + eb[org_bones[first_torso_bone]].tail)/2 + 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_b in org_bones: + def_name = make_deformer_name(strip_org(org_b)) + def_name = copy_bone(self.obj, org_b, 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 + + if not self.use_head: + return { + 'ctrl_neck': '', + 'ctrl': '', + 'mch_str': '', + 'mch_neck': '', + 'mch_head': '', + 'mch': [], + 'tweak': [], + 'neck_bend': '', + 'original_names': neck_bones + } + + neck, neck_bend = '', '' + if len(neck_bones) >= 2: + # 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 + + if len(neck_bones) > 3: + + # Create neck bend control + neck_bend = copy_bone(self.obj, org(neck_bones[0]), 'neck_bend') + neck_bend_eb = eb[neck_bend] + + # Neck pivot position + if (len(neck_bones)-1) % 2: # odd num of neck bones (head excluded) + center_bone = org(neck_bones[int((len(neck_bones))/2) - 1]) + neck_bend_eb.head = (eb[center_bone].head + eb[center_bone].tail)/2 + else: + center_bone = org(neck_bones[int((len(neck_bones)-1)/2) - 1]) + neck_bend_eb.head = eb[center_bone].tail + + align_bone_y_axis(self.obj, neck_bend, eb[neck].y_axis) + align_bone_x_axis(self.obj, neck_bend, eb[neck].x_axis) + eb[neck_bend].length = eb[neck].length / 2 + + # Create head control + head = copy_bone(self.obj, org(neck_bones[-1]), 'head') + + # MCH bones + mch_str, mch_neck = '', '' + if len(neck_bones) >= 2: + # 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 = [], [] + + if len(neck_bones) >= 2: + # 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 + align_bone_y_axis(self.obj, mch_name, eb[neck].y_axis) + align_bone_x_axis(self.obj, mch_name, eb[neck].x_axis) + eb[mch_name].use_inherit_scale = False + 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, + 'neck_bend': neck_bend, + 'original_names': neck_bones + } + + 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): + bpy.ops.object.mode_set(mode='EDIT') + eb = self.obj.data.edit_bones + org_bones = self.org_bones + + ctrl_chain = [] + for i in range(len(tail_bones)): + name = tail_bones[i] + + ctrl_bone = copy_bone( + self.obj, + org(name), + strip_org(name) + ) + + flip_bone(self.obj, ctrl_bone) + ctrl_chain.append(ctrl_bone) + + # Main ctrl + name = tail_bones[-1] + main_ctrl_bone = copy_bone( + self.obj, + org(name), + strip_org(name).split('.')[0] + "_master" + ) + flip_bone(self.obj, main_ctrl_bone) + + mch_tail = '' + tail_first = org_bones[self.tail_pos-1] + mch_rot_tail = copy_bone( + self.obj, + org(tail_first), + make_mechanism_name("ROT-tail") + ) + + self.orient_bone(eb[mch_rot_tail], 'y', eb[tail_first].length) + put_bone(self.obj, mch_rot_tail, eb[tail_first].tail) + mch_tail = mch_rot_tail + + tweak_chain = [] + for i in range(len(tail_bones)): + name = tail_bones[i] + + tweak_bone = copy_bone( + self.obj, + org(name), + "tweak_" + strip_org(name) + ) + + tweak_e = eb[tweak_bone] + tweak_e.length /= 2 # Set size to half + + # Position tweaks + flip_bone(self.obj, tweak_bone) + put_bone(self.obj, tweak_bone, eb[org(name)].head) + + tweak_chain.append(tweak_bone) + + return { + 'ctrl': ctrl_chain, + 'ctrl_tail': main_ctrl_bone, + 'mch_tail': mch_tail, + 'tweak': tweak_chain, + 'original_names': tail_bones + } + + 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 + if self.use_head: + eb[bones['neck']['ctrl']].parent = eb[bones['neck']['mch_head']] + + # Tail control chain + if self.use_tail: + tail_ctrl = bones['tail']['ctrl'] + for i, b in enumerate(tail_ctrl[:-1]): + eb[b].parent = eb[tail_ctrl[i+1]] + eb[tail_ctrl[-1]].parent = eb[bones['tail']['mch_tail']] + eb[bones['tail']['ctrl_tail']].parent = eb[org_bones[self.tail_pos]] + + if bones['neck']['ctrl_neck']: + # 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']] + + # Neck pivot => MCH-rotation_neck + if bones['neck']['neck_bend']: + # eb[bones['neck']['neck_bend']].parent = eb[bones['neck']['ctrl_neck']] + eb[bones['neck']['neck_bend']].parent = eb[bones['neck']['mch_str']] + + # 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 + if bones['neck']['ctrl_neck']: + # Neck mch + eb[bones['neck']['mch_head']].parent = eb[bones['neck']['ctrl_neck']] + elif self.use_head: + eb[bones['neck']['mch_head']].parent = eb[bones['chest']['mch'][-1]] + + for i, b in enumerate([eb[n] for n in bones['neck']['mch']]): + b.parent = eb[bones['neck']['mch_str']] + # for org_b in bones['neck']['original_names']: + # if org_b in b.name: + # b.parent = eb[org(org_b)] + + # 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']] + elif b: + 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]] + + # Neck Tweaks + if bones['neck']['tweak']: + # 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]] + + # Tail mchs + if self.use_tail: + mch_rot_tail = bones['tail']['mch_tail'] + eb[mch_rot_tail].parent = eb[bones['hips']['tweak'][0]] + + # Tail tweaks + if self.use_tail: + for i, twk in enumerate(bones['tail']['tweak']): + if i == 0: + eb[twk].parent = eb[bones['tail']['ctrl'][i]] + else: + eb[twk].parent = eb[bones['tail']['ctrl'][i-1]] + + # Parent orgs to matching tweaks + tweaks = [] + if self.use_tail: + tweaks += bones['tail']['tweak'] + + tweaks += bones['hips']['tweak'] + bones['chest']['tweak'] + if self.use_head: + tweaks += bones['neck']['tweak'] + [bones['neck']['ctrl']] + + original_neck_bones = [org(b) for b in bones['neck']['original_names']] + original_neck_bones = original_neck_bones[1:-1] # exclude first neck bone and head + for b, twk in zip(org_bones[:-1], tweaks): + if b in original_neck_bones and len(bones['neck']['original_names']) > 3: + idx = org_bones.index(b) + org_parent = org_bones[idx-1] + eb[b].parent = eb[org_parent] + else: + eb[b].parent = eb[twk] + + if self.use_head: + eb[org_bones[-1]].parent = eb[bones['neck']['ctrl']] + + 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']]: + if b: + self.make_constraint(b, { + 'constraint': 'COPY_ROTATION', + 'subtarget': bones['pivot']['ctrl'], + }) + self.make_constraint(b, { + 'constraint': 'COPY_SCALE', + 'subtarget': bones['pivot']['ctrl'], + }) + + if bones['neck']['mch_str']: + # 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']] + + for i, l in enumerate(intermediaries): + mch = l['mch'] + + for j, b in enumerate(mch): + + if i == 0: # Neck mch-s + if len(bones['neck']['original_names']) > 3: + self.make_constraint(b, { + 'constraint': 'COPY_LOCATION', + 'subtarget': org(l['original_names'][j+1]), + 'influence': 1.0 + }) + else: + nfactor = float((j + 1) / len(mch)) + self.make_constraint(b, { + 'constraint': 'COPY_ROTATION', + 'subtarget': l['ctrl'], + 'influence': nfactor + }) + + step = 2/(len(mch)+1) + xval = (j+1)*step + influence = 2*xval - xval**2 #parabolic influence of pivot + + if bones['neck']['neck_bend']: + self.make_constraint(b, { + 'constraint': 'COPY_LOCATION', + 'subtarget': l['neck_bend'], + 'influence': influence, + 'use_offset': True, + 'owner_space': 'LOCAL', + 'target_space': 'LOCAL' + }) + + if len(bones['neck']['original_names']) > 3: + self.make_constraint(b, { + 'constraint': 'COPY_SCALE', + 'subtarget': org(l['original_names'][j+1]), + 'influence': 1.0 + }) + + else: + factor = float(1 / len(l['tweak'])) + self.make_constraint(b, { + 'constraint': 'COPY_TRANSFORMS', + 'subtarget': l['ctrl'], + 'influence': factor, + 'owner_space': 'LOCAL', + 'target_space': 'LOCAL' + }) + + # Tail ctrls + if self.use_tail: + tail_ctrl = bones['tail']['ctrl'] + tail_ctrl.append(bones['tail']['ctrl_tail']) + + for i, b in enumerate(tail_ctrl[:-1]): + self.make_constraint(b, { + 'constraint': 'COPY_ROTATION', + 'subtarget': tail_ctrl[i+1], + 'influence': 1.0, + 'use_x': self.copy_rotation_axes[0], + 'use_y': self.copy_rotation_axes[1], + 'use_z': self.copy_rotation_axes[2], + 'use_offset': True, + 'owner_space': 'LOCAL', + 'target_space': 'LOCAL' + }) + + b = bones['tail']['mch_tail'] + self.make_constraint(b, { + 'constraint': 'COPY_ROTATION', + 'subtarget': bones['pivot']['ctrl'], + 'influence': 1.0, + }) + + # 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 = [] + if self.use_tail: + tweaks += bones['tail']['tweak'] + + tweaks += bones['hips']['tweak'] + bones['chest']['tweak'] + if self.use_head: + 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: + if self.use_tail and t in bones['tail']['tweak']: + self.make_constraint(d, { + 'constraint': 'DAMPED_TRACK', + 'subtarget': tweaks[tidx + 1], + 'track_axis': 'TRACK_NEGATIVE_Y' + }) + else: + 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 + + if bones['neck']['neck_bend']: + pb[bones['neck']['neck_bend']].rotation_mode = 'ZXY' + pb[bones['neck']['neck_bend']].lock_rotation[0] = True + pb[bones['neck']['neck_bend']].lock_rotation[2] = True + + for t in tweaks: + if t != bones['neck']['ctrl']: + pb[t].rotation_mode = 'ZXY' + + original_neck_bones = [org(b) for b in bones['neck']['original_names']] + # make IK on neck ORGs + if len(original_neck_bones) > 3: + last_neck = original_neck_bones[-2] + self.make_constraint(last_neck, { + 'constraint': 'IK', + 'subtarget': bones['neck']['ctrl'], + 'chain_count': len(original_neck_bones) - 1 + }) + + for b in original_neck_bones[:-1]: + pb[b].ik_stretch = 0.1 + + 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 = [] + owners = [] + + if self.use_head: + props += ["head_follow"] + owners += [bones['neck']['mch_head']] + if bones['neck']['mch_neck']: + props += ["neck_follow"] + owners += [bones['neck']['mch_neck']] + if self.use_tail: + props += ["tail_follow"] + owners += [bones['tail']['mch_tail']] + + 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 + self.obj.data.bones[bones['def'][-2]].bbone_out = 1.0 + + # Locks + tweaks = bones['neck']['tweak'] + bones['chest']['tweak'] + tweaks += bones['hips']['tweak'] + + if self.use_tail: + tweaks += bones['tail']['tweak'] + pb[bones['tail']['ctrl_tail']].lock_location = True, True, True + + # 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['chest']['ctrl'], + bones['hips']['ctrl'] + ] + + tail_ctrls = [] + if self.use_tail and bones['tail']['ctrl']: + tail_ctrls = bones['tail']['ctrl'] + [bones['tail']['ctrl_tail']] + gen_ctrls.extend(bones['tail']['ctrl']) + + create_ballsocket_widget( + self.obj, + bones['tail']['ctrl_tail'], + size=0.7, + bone_transform_name=None + ) + + for bone in gen_ctrls: + + if bone in tail_ctrls: + radius = 0.5 + else: + radius = 1.0 + + create_circle_widget( + self.obj, + bone, + radius=radius, + head_tail=0.75, + with_line=False, + bone_transform_name=None + ) + + if bones['neck']['ctrl_neck']: + # Neck ctrl widget + if len(bones['neck']['mch']) == 0: + radius = 1 + else: + radius = 1/(len(bones['neck']['mch'])) + create_circle_widget( + self.obj, + bones['neck']['ctrl_neck'], + radius=radius, + head_tail=0.75, + with_line=False, + bone_transform_name=None + ) + + if bones['neck']['neck_bend']: + # Neck pivot widget + if len(bones['neck']['mch']) == 0: + radius = 0.5 + else: + radius = 1/(2*len(bones['neck']['mch'])) + create_circle_widget( + self.obj, + bones['neck']['neck_bend'], + radius=radius, + head_tail=0.0, + with_line=False, + bone_transform_name=None + ) + + # Head widget + if self.use_head: + create_circle_widget( + self.obj, + bones['neck']['ctrl'], + radius = 0.5, + 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 self.use_tail: + hips_widget_loc = pb[bones['def'][self.tail_pos]] + pb[bones['tail']['ctrl_tail']].custom_shape_transform = pb[bones['tail']['tweak'][0]] + + 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) + + else: + return + + controls = [bones['neck']['ctrl'], bones['neck']['ctrl_neck']] + controls += [bones['chest']['ctrl'], bones['hips']['ctrl']] + controls += [bones['pivot']['ctrl']] + + if self.use_tail: + controls.extend(bones['tail']['ctrl']) + + # Create UI + controls_string = ", ".join(["'" + x + "'" for x in controls]) + return [script % ( + controls_string, + bones['pivot']['ctrl'], + 'head_follow', + 'head_follow', + 'neck_follow', + 'neck_follow', + 'tail_follow', + 'tail_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.copy_rotation_axes = bpy.props.BoolVectorProperty( + size=3, + description="Automation axes", + default=tuple([i == 0 for i in range(0, 3)]) + ) + + params.tail_pos = bpy.props.IntProperty( + name = 'tail_position', + default = 0, + min = 2, + description = 'Where the tail starts' + ) + + params.use_tail = bpy.props.BoolProperty( + name='use_tail', + default=False, + description='Create tail bones' + ) + + params.use_head = bpy.props.BoolProperty( + name='use_head', + default=True, + description='Create head and neck bones' + ) + + # 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(align=True) + r.prop(params, "use_head", toggle=True, text="Head") + r.prop(params, "use_tail", toggle=True, text="Tail") + + r = layout.row() + r.prop(params, "neck_pos") + r.enabled = params.use_head + + r = layout.row() + r.prop(params, "pivot_pos") + + r = layout.row() + r.prop(params, "tail_pos") + r.enabled = params.use_tail + + 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_rotation_axes", index=i, toggle=True, text=axis) + r.enabled = params.use_tail + + 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.013, 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.013, 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 = 'spines.super_spine' + 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/rigs/widgets.py b/rigify/rigs/widgets.py new file mode 100644 index 0000000000000000000000000000000000000000..0d3e9305a4d2e6604221a04fe8456f597dbfb950 --- /dev/null +++ b/rigify/rigs/widgets.py @@ -0,0 +1,181 @@ +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 + + +def create_gear_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.11251477152109146*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (0.018439611420035362*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (0.09270283579826355*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (0.08732416480779648*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), (0.07858962565660477*size, -2.295374557093055e-09*size, 0.05251204967498779*size), (0.052511852234601974*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), (0.03617073595523834*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), (0.018439611420035362*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), (0.09402976930141449*size, -2.937612375575327e-09*size, 0.06720473617315292*size), (0.08150213211774826*size, -3.513068946858766e-09*size, 0.08036965131759644*size), (0.06872907280921936*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), (-0.1125146746635437*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (-0.01843959279358387*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (1.078764189088588e-08*size, -4.918176976786981e-09*size, 0.11251477152109146*size), (-0.09270282834768295*size, -8.06030631128607e-10*size, 0.01843983121216297*size), (-0.0873241126537323*size, -1.5810827092010982e-09*size, 0.03617095574736595*size), (-0.07858961820602417*size, -2.295374557093055e-09*size, 0.05251204967498779*size), (-0.05251181498169899*size, -3.4352671818282943e-09*size, 0.07858975231647491*size), (-0.036170728504657745*size, -3.8170644423018985e-09*size, 0.08732425421476364*size), (-0.01843959279358387*size, -4.0521714872454595e-09*size, 0.09270287305116653*size), (-0.09402971714735031*size, -2.937612375575327e-09*size, 0.06720473617315292*size), (-0.08150212466716766*size, -3.513068946858766e-09*size, 0.08036965131759644*size), (-0.06872902065515518*size, -4.0997978345558295e-09*size, 0.09379243850708008*size), (0.11251477152109146*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (0.11251477152109146*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), (0.018439611420035362*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (0.09270283579826355*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (0.08732416480779648*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), (0.07858962565660477*size, 2.29537477913766e-09*size, -0.05251205340027809*size), (0.052511852234601974*size, 3.435267403872899e-09*size, -0.07858975976705551*size), (0.03617073595523834*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), (0.018439611420035362*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), (0.09402976930141449*size, 2.937614596021376e-09*size, -0.0672047883272171*size), (0.08150213211774826*size, 3.513068946858766e-09*size, -0.08036965131759644*size), (0.06872907280921936*size, 4.099800055001879e-09*size, -0.09379249066114426*size), (-0.1125146746635437*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (-0.1125146746635437*size, 3.801315519479033e-16*size, -8.696396491814085e-09*size), (-0.01843959279358387*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (1.078764189088588e-08*size, 4.918176532697771e-09*size, -0.11251476407051086*size), (-0.09270282834768295*size, 8.06031352773573e-10*size, -0.018439847975969315*size), (-0.0873241126537323*size, 1.5810828202234006e-09*size, -0.03617095947265625*size), (-0.07858961820602417*size, 2.29537477913766e-09*size, -0.05251205340027809*size), (-0.05251181498169899*size, 3.435267403872899e-09*size, -0.07858975976705551*size), (-0.036170728504657745*size, 3.8170644423018985e-09*size, -0.08732425421476364*size), (-0.01843959279358387*size, 4.0521714872454595e-09*size, -0.09270287305116653*size), (-0.09402971714735031*size, 2.937614596021376e-09*size, -0.0672047883272171*size), (-0.08150212466716766*size, 3.513068946858766e-09*size, -0.08036965131759644*size), (-0.06872902065515518*size, 4.099800055001879e-09*size, -0.09379249066114426*size), ] + edges = [(0, 2), (0, 24), (7, 1), (13, 1), (3, 2), (4, 3), (6, 5), (7, 6), (9, 8), (10, 9), (10, 5), (4, 8), (11, 14), (11, 36), (19, 12), (13, 12), (15, 14), (16, 15), (18, 17), (19, 18), (21, 20), (22, 21), (22, 17), (16, 20), (23, 26), (23, 24), (31, 25), (38, 25), (27, 26), (28, 27), (30, 29), (31, 30), (33, 32), (34, 33), (34, 29), (28, 32), (35, 39), (35, 36), (44, 37), (38, 37), (40, 39), (41, 40), (43, 42), (44, 43), (46, 45), (47, 46), (47, 42), (41, 45), ] + faces = [] + mesh = obj.data + mesh.from_pydata(verts, edges, faces) + mesh.update() + mesh.update() + return obj + else: + return None + diff --git a/rigify/ui.py b/rigify/ui.py index dec5b73c8a8e8462959f7b95fd9784ebf636c6be..689911052951dd29f9719e15fe9cd2ee69d98fa2 100644 --- a/rigify/ui.py +++ b/rigify/ui.py @@ -36,13 +36,7 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): @classmethod def poll(cls, context): - if not context.armature: - return False - #obj = context.object - #if obj: - # return (obj.mode in {'POSE', 'OBJECT', 'EDIT'}) - #return False - return True + return context.object.type == 'ARMATURE' def draw(self, context): C = context @@ -52,6 +46,21 @@ class DATA_PT_rigify_buttons(bpy.types.Panel): if obj.mode in {'POSE', 'OBJECT'}: layout.operator("pose.rigify_generate", text="Generate") + WARNING = "Warning: Some features may change after generation" + show_warning = False + + check_props = ['IK_follow', 'root/parent', 'FK_limb_follow', 'IK_Stretch'] + for obj in bpy.data.objects: + if type(obj.data) != bpy.types.Armature: + continue + for bone in obj.pose.bones: + if bone.bone.layers[30] and (list(set(bone.keys()) & set(check_props))): + show_warning = True + break + + if show_warning: + layout.label(text=WARNING, icon='ERROR') + elif obj.mode == 'EDIT': # Build types list collection_name = str(id_store.rigify_collection).replace(" ", "") @@ -92,9 +101,7 @@ class DATA_PT_rigify_layer_names(bpy.types.Panel): @classmethod def poll(cls, context): - if not context.armature: - return False - return True + return context.object.type == 'ARMATURE' def draw(self, context): layout = self.layout @@ -161,6 +168,9 @@ class BONE_PT_rigify_buttons(bpy.types.Panel): id_store.rigify_types.remove(0) for r in rig_lists.rig_list: + rig = get_rig_type(r) + if hasattr(rig, 'IMPLEMENTATION') and rig.IMPLEMENTATION: + continue # collection = r.split('.')[0] # UNUSED if collection_name == "All": a = id_store.rigify_types.add() @@ -204,10 +214,6 @@ class VIEW3D_PT_tools_rigify_dev(bpy.types.Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' - @classmethod - def poll(cls, context): - return context.active_object is not None and context.mode in {'EDIT_ARMATURE','EDIT_MESH'} - def draw(self, context): obj = context.active_object if obj is not None: diff --git a/rigify/utils.py b/rigify/utils.py index dc9897ac5e488d732ffb838fa01959c141d546f9..0225a8461e3c04a6a22db645918f4facdea7b257 100644 --- a/rigify/utils.py +++ b/rigify/utils.py @@ -19,7 +19,7 @@ # <pep8 compliant> import bpy -import importlib +import imp import importlib import math import random @@ -135,6 +135,7 @@ def new_bone(obj, bone_name): else: raise MetarigError("Can't add new bone '%s' outside of edit mode" % bone_name) + def copy_bone_simple(obj, bone_name, assign_name=''): """ Makes a copy of the given bone in the given armature object. but only copies head, tail positions and roll. Does not @@ -151,7 +152,7 @@ def copy_bone_simple(obj, bone_name, assign_name=''): edit_bone_1 = obj.data.edit_bones[bone_name] edit_bone_2 = obj.data.edit_bones.new(assign_name) bone_name_1 = bone_name - bone_name_2 = edit_bone_2.name + bone_name_2 = edit_bone_2.name # Copy edit bone attributes edit_bone_2.layers = list(edit_bone_1.layers) @@ -164,6 +165,7 @@ def copy_bone_simple(obj, bone_name, assign_name=''): else: raise MetarigError("Cannot copy bones outside of edit mode") + def copy_bone(obj, bone_name, assign_name=''): """ Makes a copy of the given bone in the given armature object. Returns the resulting bone's name. @@ -354,41 +356,6 @@ def obj_to_bone(obj, rig, bone_name): obj.scale = (bone.length * scl_avg), (bone.length * scl_avg), (bone.length * scl_avg) -def create_circle_polygon(number_verts, axis, radius=1.0, head_tail=0.0): - """ Creates a basic circle around of an axis selected. - number_verts: number of vertices of the poligon - axis: axis normal to the circle - radius: the radius of the circle - head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail) - """ - verts = [] - edges = [] - angle = 2 * math.pi / number_verts - i = 0 - - assert(axis in 'XYZ') - - while i < (number_verts): - a = math.cos(i * angle) - b = math.sin(i * angle) - - if axis == 'X': - verts.append((head_tail, a * radius, b * radius)) - elif axis == 'Y': - verts.append((a * radius, head_tail, b * radius)) - elif axis == 'Z': - verts.append((a * radius, b * radius, head_tail)) - - if i < (number_verts - 1): - edges.append((i , i + 1)) - - i += 1 - - edges.append((0, number_verts - 1)) - - return verts, edges - - def create_widget(rig, bone_name, bone_transform_name=None): """ Creates an empty widget object for a bone, and returns the object. """ @@ -420,6 +387,8 @@ def create_widget(rig, bone_name, bone_transform_name=None): # Move object to bone position and set layers obj_to_bone(obj, rig, bone_transform_name) + if 'WGTS' in bpy.data.objects.keys(): + obj.parent = bpy.data.objects['WGTS'] obj.layers = WGT_LAYERS return obj @@ -443,12 +412,13 @@ def create_circle_widget(rig, bone_name, radius=1.0, head_tail=0.0, with_line=Fa head_tail: where along the length of the bone the circle is (0.0=head, 1.0=tail) """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - verts, edges = create_circle_polygon(32, 'Y', radius, head_tail) - + if obj != None: + v = [(0.7071068286895752, 2.980232238769531e-07, -0.7071065306663513), (0.8314696550369263, 2.980232238769531e-07, -0.5555699467658997), (0.9238795042037964, 2.682209014892578e-07, -0.3826831877231598), (0.9807852506637573, 2.5331974029541016e-07, -0.19509011507034302), (1.0, 2.365559055306221e-07, 1.6105803979371558e-07), (0.9807853698730469, 2.2351741790771484e-07, 0.19509044289588928), (0.9238796234130859, 2.086162567138672e-07, 0.38268351554870605), (0.8314696550369263, 1.7881393432617188e-07, 0.5555704236030579), (0.7071068286895752, 1.7881393432617188e-07, 0.7071070075035095), (0.5555702447891235, 1.7881393432617188e-07, 0.8314698934555054), (0.38268327713012695, 1.7881393432617188e-07, 0.923879861831665), (0.19509008526802063, 1.7881393432617188e-07, 0.9807855486869812), (-3.2584136988589307e-07, 1.1920928955078125e-07, 1.000000238418579), (-0.19509072601795197, 1.7881393432617188e-07, 0.9807854294776917), (-0.3826838731765747, 1.7881393432617188e-07, 0.9238795638084412), (-0.5555707216262817, 1.7881393432617188e-07, 0.8314695358276367), (-0.7071071863174438, 1.7881393432617188e-07, 0.7071065902709961), (-0.8314700126647949, 1.7881393432617188e-07, 0.5555698871612549), (-0.923879861831665, 2.086162567138672e-07, 0.3826829195022583), (-0.9807853698730469, 2.2351741790771484e-07, 0.1950896978378296), (-1.0, 2.365559907957504e-07, -7.290432222362142e-07), (-0.9807850122451782, 2.5331974029541016e-07, -0.195091113448143), (-0.9238790273666382, 2.682209014892578e-07, -0.38268423080444336), (-0.831468939781189, 2.980232238769531e-07, -0.5555710196495056), (-0.7071058750152588, 2.980232238769531e-07, -0.707107424736023), (-0.555569052696228, 2.980232238769531e-07, -0.8314701318740845), (-0.38268208503723145, 2.980232238769531e-07, -0.923879861831665), (-0.19508881866931915, 2.980232238769531e-07, -0.9807853102684021), (1.6053570561780361e-06, 2.980232238769531e-07, -0.9999997615814209), (0.19509197771549225, 2.980232238769531e-07, -0.9807847142219543), (0.3826850652694702, 2.980232238769531e-07, -0.9238786101341248), (0.5555717945098877, 2.980232238769531e-07, -0.8314683437347412)] + verts = [(a[0] * radius, head_tail, a[2] * radius) for a in v] if with_line: - edges.append((8, 24)) - + edges = [(28, 12), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] + else: + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] mesh = obj.data mesh.from_pydata(verts, edges, []) mesh.update() @@ -469,26 +439,29 @@ def create_cube_widget(rig, bone_name, radius=0.5, bone_transform_name=None): mesh.from_pydata(verts, edges, []) mesh.update() +def create_chain_widget(rig, bone_name, radius=0.5, invert=False, bone_transform_name=None): + """Creates a basic chain widget + """ + obj = create_widget(rig, bone_name, bone_transform_name) + if obj != None: + r = radius + rh = radius/2 + if invert: + verts = [(rh, rh, rh), (r, -r, r), (-r, -r, r), (-rh, rh, rh), (rh, rh, -rh), (r, -r, -r), (-r, -r, -r), (-rh, rh, -rh)] + else: + verts = [(r, r, r), (rh, -rh, rh), (-rh, -rh, rh), (-r, r, r), (r, r, -r), (rh, -rh, -rh), (-rh, -rh, -rh), (-r, r, -r)] + edges = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4), (0, 4), (1, 5), (2, 6), (3, 7)] + mesh = obj.data + mesh.from_pydata(verts, edges, []) + mesh.update() def create_sphere_widget(rig, bone_name, bone_transform_name=None): """ Creates a basic sphere widget, three pependicular overlapping circles. """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - verts_x, edges_x = create_circle_polygon(16, 'X', 0.5) - verts_y, edges_y = create_circle_polygon(16, 'Y', 0.5) - verts_z, edges_z = create_circle_polygon(16, 'Z', 0.5) - - verts = verts_x + verts_y + verts_z - - edges = [ - (0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), - (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), - (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), - (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (16, 31), - (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), - (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47), - ] + if obj != None: + verts = [(0.3535533845424652, 0.3535533845424652, 0.0), (0.4619397521018982, 0.19134171307086945, 0.0), (0.5, -2.1855694143368964e-08, 0.0), (0.4619397521018982, -0.19134175777435303, 0.0), (0.3535533845424652, -0.3535533845424652, 0.0), (0.19134174287319183, -0.4619397521018982, 0.0), (7.549790126404332e-08, -0.5, 0.0), (-0.1913416087627411, -0.46193981170654297, 0.0), (-0.35355329513549805, -0.35355350375175476, 0.0), (-0.4619397521018982, -0.19134178757667542, 0.0), (-0.5, 5.962440319251527e-09, 0.0), (-0.4619397222995758, 0.1913418024778366, 0.0), (-0.35355326533317566, 0.35355350375175476, 0.0), (-0.19134148955345154, 0.46193987131118774, 0.0), (3.2584136988589307e-07, 0.5, 0.0), (0.1913420855998993, 0.46193960309028625, 0.0), (7.450580596923828e-08, 0.46193960309028625, 0.19134199619293213), (5.9254205098113744e-08, 0.5, 2.323586443253589e-07), (4.470348358154297e-08, 0.46193987131118774, -0.1913415789604187), (2.9802322387695312e-08, 0.35355350375175476, -0.3535533547401428), (2.9802322387695312e-08, 0.19134178757667542, -0.46193981170654297), (5.960464477539063e-08, -1.1151834122813398e-08, -0.5000000596046448), (5.960464477539063e-08, -0.1913418024778366, -0.46193984150886536), (5.960464477539063e-08, -0.35355350375175476, -0.3535533845424652), (7.450580596923828e-08, -0.46193981170654297, -0.19134166836738586), (9.348272556053416e-08, -0.5, 1.624372103492533e-08), (1.043081283569336e-07, -0.4619397521018982, 0.19134168326854706), (1.1920928955078125e-07, -0.3535533845424652, 0.35355329513549805), (1.1920928955078125e-07, -0.19134174287319183, 0.46193966269493103), (1.1920928955078125e-07, -4.7414250303745575e-09, 0.49999991059303284), (1.1920928955078125e-07, 0.19134172797203064, 0.46193966269493103), (8.940696716308594e-08, 0.3535533845424652, 0.35355329513549805), (0.3535534739494324, 0.0, 0.35355329513549805), (0.1913418173789978, -2.9802322387695312e-08, 0.46193966269493103), (8.303572940349113e-08, -5.005858838558197e-08, 0.49999991059303284), (-0.19134165346622467, -5.960464477539063e-08, 0.46193966269493103), (-0.35355329513549805, -8.940696716308594e-08, 0.35355329513549805), (-0.46193963289260864, -5.960464477539063e-08, 0.19134168326854706), (-0.49999991059303284, -5.960464477539063e-08, 1.624372103492533e-08), (-0.4619397521018982, -2.9802322387695312e-08, -0.19134166836738586), (-0.3535534143447876, -2.9802322387695312e-08, -0.3535533845424652), (-0.19134171307086945, 0.0, -0.46193984150886536), (7.662531942287387e-08, 9.546055501630235e-09, -0.5000000596046448), (0.19134187698364258, 5.960464477539063e-08, -0.46193981170654297), (0.3535535931587219, 5.960464477539063e-08, -0.3535533547401428), (0.4619399905204773, 5.960464477539063e-08, -0.1913415789604187), (0.5000000596046448, 5.960464477539063e-08, 2.323586443253589e-07), (0.4619396924972534, 2.9802322387695312e-08, 0.19134199619293213)] + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (0, 15), (16, 31), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (32, 33), (33, 34), (34, 35), (35, 36), (36, 37), (37, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (32, 47)] mesh = obj.data mesh.from_pydata(verts, edges, []) mesh.update() @@ -499,11 +472,9 @@ def create_limb_widget(rig, bone_name, bone_transform_name=None): bone, with a circle around the center. """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - verts, edges = create_circle_polygon(32, "Y", 0.25, 0.5) - verts.append((0, 0, 0)) - verts.append((0, 1, 0)) - edges.append((32, 33)) + if obj != None: + verts = [(-1.1920928955078125e-07, 1.7881393432617188e-07, 0.0), (3.5762786865234375e-07, 1.0000004768371582, 0.0), (0.1767769455909729, 0.5000001192092896, 0.17677664756774902), (0.20786768198013306, 0.5000001192092896, 0.1388925313949585), (0.23097014427185059, 0.5000001192092896, 0.09567084908485413), (0.24519658088684082, 0.5000001192092896, 0.048772573471069336), (0.2500002384185791, 0.5000001192092896, -2.545945676502015e-09), (0.24519658088684082, 0.5000001192092896, -0.048772573471069336), (0.23097014427185059, 0.5000001192092896, -0.09567084908485413), (0.20786768198013306, 0.5000001192092896, -0.13889259099960327), (0.1767769455909729, 0.5000001192092896, -0.1767767071723938), (0.13889282941818237, 0.5000001192092896, -0.20786744356155396), (0.09567105770111084, 0.5000001192092896, -0.23096990585327148), (0.04877278208732605, 0.5000001192092896, -0.24519634246826172), (1.7279069197684294e-07, 0.5000000596046448, -0.25), (-0.0487724244594574, 0.5000001192092896, -0.24519634246826172), (-0.09567070007324219, 0.5000001192092896, -0.2309698462486267), (-0.13889241218566895, 0.5000001192092896, -0.20786738395690918), (-0.17677652835845947, 0.5000001192092896, -0.17677664756774902), (-0.20786726474761963, 0.5000001192092896, -0.13889244198799133), (-0.23096972703933716, 0.5000001192092896, -0.09567070007324219), (-0.24519610404968262, 0.5000001192092896, -0.04877239465713501), (-0.2499997615814209, 0.5000001192092896, 2.1997936983098043e-07), (-0.24519598484039307, 0.5000001192092896, 0.04877282679080963), (-0.23096948862075806, 0.5000001192092896, 0.09567108750343323), (-0.20786696672439575, 0.5000001192092896, 0.1388927698135376), (-0.1767762303352356, 0.5000001192092896, 0.17677688598632812), (-0.13889199495315552, 0.5000001192092896, 0.2078675627708435), (-0.09567028284072876, 0.5000001192092896, 0.23097002506256104), (-0.048771947622299194, 0.5000001192092896, 0.24519634246826172), (6.555903269145347e-07, 0.5000001192092896, 0.25), (0.04877324402332306, 0.5000001192092896, 0.24519622325897217), (0.09567153453826904, 0.5000001192092896, 0.23096966743469238), (0.13889318704605103, 0.5000001192092896, 0.20786714553833008)] + edges = [(0, 1), (2, 3), (4, 3), (5, 4), (5, 6), (6, 7), (8, 7), (8, 9), (10, 9), (10, 11), (11, 12), (13, 12), (14, 13), (14, 15), (16, 15), (16, 17), (17, 18), (19, 18), (19, 20), (21, 20), (21, 22), (22, 23), (24, 23), (25, 24), (25, 26), (27, 26), (27, 28), (29, 28), (29, 30), (30, 31), (32, 31), (32, 33), (2, 33)] mesh = obj.data mesh.from_pydata(verts, edges, []) mesh.update() @@ -513,7 +484,7 @@ def create_bone_widget(rig, bone_name, bone_transform_name=None): """ Creates a basic bone widget, a simple obolisk-esk shape. """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: + if obj != None: verts = [(0.04, 1.0, -0.04), (0.1, 0.0, -0.1), (-0.1, 0.0, -0.1), (-0.04, 1.0, -0.04), (0.04, 1.0, 0.04), (0.1, 0.0, 0.1), (-0.1, 0.0, 0.1), (-0.04, 1.0, 0.04)] edges = [(1, 2), (0, 1), (0, 3), (2, 3), (4, 5), (5, 6), (6, 7), (4, 7), (1, 5), (0, 4), (2, 6), (3, 7)] mesh = obj.data @@ -525,14 +496,9 @@ def create_compass_widget(rig, bone_name, bone_transform_name=None): """ Creates a compass-shaped widget. """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: - verts, edges = create_circle_polygon(32, "Z", 1.0, 0.0) - i = 0 - for v in verts: - if i in {0, 8, 16, 24}: - verts[i] = (v[0] * 1.2, v[1] * 1.2, v[2]) - i += 1 - + if obj != None: + verts = [(0.0, 1.2000000476837158, 0.0), (0.19509032368659973, 0.9807852506637573, 0.0), (0.3826834559440613, 0.9238795042037964, 0.0), (0.5555702447891235, 0.8314695954322815, 0.0), (0.7071067690849304, 0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (1.2000000476837158, 7.549790126404332e-08, 0.0), (0.9807853102684021, -0.19509020447731018, 0.0), (0.9238795638084412, -0.38268327713012695, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (0.5555701851844788, -0.8314696550369263, 0.0), (0.38268327713012695, -0.9238796234130859, 0.0), (0.19509008526802063, -0.9807853102684021, 0.0), (-3.2584136988589307e-07, -1.2999999523162842, 0.0), (-0.19509072601795197, -0.9807851910591125, 0.0), (-0.3826838731765747, -0.9238793253898621, 0.0), (-0.5555707216262817, -0.8314692974090576, 0.0), (-0.7071072459220886, -0.707106351852417, 0.0), (-0.8314700126647949, -0.5555696487426758, 0.0), (-0.923879861831665, -0.3826826810836792, 0.0), (-0.9807854294776917, -0.1950894594192505, 0.0), (-1.2000000476837158, 9.655991561885457e-07, 0.0), (-0.980785071849823, 0.1950913518667221, 0.0), (-0.923879086971283, 0.38268446922302246, 0.0), (-0.831468939781189, 0.5555712580680847, 0.0), (-0.7071058750152588, 0.707107663154602, 0.0), (-0.5555691123008728, 0.8314703702926636, 0.0), (-0.38268208503723145, 0.9238801002502441, 0.0), (-0.19508881866931915, 0.9807855486869812, 0.0)] + edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19), (19, 20), (20, 21), (21, 22), (22, 23), (23, 24), (24, 25), (25, 26), (26, 27), (27, 28), (28, 29), (29, 30), (30, 31), (0, 31)] mesh = obj.data mesh.from_pydata(verts, edges, []) mesh.update() @@ -542,7 +508,7 @@ def create_root_widget(rig, bone_name, bone_transform_name=None): """ Creates a widget for the root bone. """ obj = create_widget(rig, bone_name, bone_transform_name) - if obj is not None: + if obj != None: verts = [(0.7071067690849304, 0.7071067690849304, 0.0), (0.7071067690849304, -0.7071067690849304, 0.0), (-0.7071067690849304, 0.7071067690849304, 0.0), (-0.7071067690849304, -0.7071067690849304, 0.0), (0.8314696550369263, 0.5555701851844788, 0.0), (0.8314696550369263, -0.5555701851844788, 0.0), (-0.8314696550369263, 0.5555701851844788, 0.0), (-0.8314696550369263, -0.5555701851844788, 0.0), (0.9238795042037964, 0.3826834261417389, 0.0), (0.9238795042037964, -0.3826834261417389, 0.0), (-0.9238795042037964, 0.3826834261417389, 0.0), (-0.9238795042037964, -0.3826834261417389, 0.0), (0.9807852506637573, 0.19509035348892212, 0.0), (0.9807852506637573, -0.19509035348892212, 0.0), (-0.9807852506637573, 0.19509035348892212, 0.0), (-0.9807852506637573, -0.19509035348892212, 0.0), (0.19509197771549225, 0.9807849526405334, 0.0), (0.19509197771549225, -0.9807849526405334, 0.0), (-0.19509197771549225, 0.9807849526405334, 0.0), (-0.19509197771549225, -0.9807849526405334, 0.0), (0.3826850652694702, 0.9238788485527039, 0.0), (0.3826850652694702, -0.9238788485527039, 0.0), (-0.3826850652694702, 0.9238788485527039, 0.0), (-0.3826850652694702, -0.9238788485527039, 0.0), (0.5555717945098877, 0.8314685821533203, 0.0), (0.5555717945098877, -0.8314685821533203, 0.0), (-0.5555717945098877, 0.8314685821533203, 0.0), (-0.5555717945098877, -0.8314685821533203, 0.0), (0.19509197771549225, 1.2807848453521729, 0.0), (0.19509197771549225, -1.2807848453521729, 0.0), (-0.19509197771549225, 1.2807848453521729, 0.0), (-0.19509197771549225, -1.2807848453521729, 0.0), (1.280785322189331, 0.19509035348892212, 0.0), (1.280785322189331, -0.19509035348892212, 0.0), (-1.280785322189331, 0.19509035348892212, 0.0), (-1.280785322189331, -0.19509035348892212, 0.0), (0.3950919806957245, 1.2807848453521729, 0.0), (0.3950919806957245, -1.2807848453521729, 0.0), (-0.3950919806957245, 1.2807848453521729, 0.0), (-0.3950919806957245, -1.2807848453521729, 0.0), (1.280785322189331, 0.39509034156799316, 0.0), (1.280785322189331, -0.39509034156799316, 0.0), (-1.280785322189331, 0.39509034156799316, 0.0), (-1.280785322189331, -0.39509034156799316, 0.0), (0.0, 1.5807849168777466, 0.0), (0.0, -1.5807849168777466, 0.0), (1.5807852745056152, 0.0, 0.0), (-1.5807852745056152, 0.0, 0.0)] edges = [(0, 4), (1, 5), (2, 6), (3, 7), (4, 8), (5, 9), (6, 10), (7, 11), (8, 12), (9, 13), (10, 14), (11, 15), (16, 20), (17, 21), (18, 22), (19, 23), (20, 24), (21, 25), (22, 26), (23, 27), (0, 24), (1, 25), (2, 26), (3, 27), (16, 28), (17, 29), (18, 30), (19, 31), (12, 32), (13, 33), (14, 34), (15, 35), (28, 36), (29, 37), (30, 38), (31, 39), (32, 40), (33, 41), (34, 42), (35, 43), (36, 44), (37, 45), (38, 44), (39, 45), (40, 46), (41, 46), (42, 47), (43, 47)] mesh = obj.data @@ -676,6 +642,19 @@ def align_bone_z_axis(obj, bone, vec): bone_e.roll += angle * 2 +def align_bone_y_axis(obj, bone, vec): + """ Matches the bone y-axis to + the given vector. + Must be in edit mode. + """ + + bone_e = obj.data.edit_bones[bone] + vec.normalize() + vec = vec * bone_e.length + + bone_e.tail = bone_e.head + vec + + #============================================= # Misc #============================================= @@ -700,7 +679,7 @@ def get_rig_type(rig_type): """ name = ".%s.%s" % (RIG_DIR, rig_type) submod = importlib.import_module(name, package=MODULE_NAME) - importlib.reload(submod) + imp.reload(submod) return submod @@ -709,7 +688,7 @@ def get_metarig_module(metarig_name): """ name = ".%s.%s" % (METARIG_DIR, metarig_name) submod = importlib.import_module(name, package=MODULE_NAME) - importlib.reload(submod) + imp.reload(submod) return submod @@ -887,7 +866,7 @@ def write_widget(obj): script = "" script += "def create_thing_widget(rig, bone_name, size=1.0, bone_transform_name=None):\n" script += " obj = create_widget(rig, bone_name, bone_transform_name)\n" - script += " if obj is not None:\n" + script += " if obj != None:\n" # Vertices if len(obj.data.vertices) > 0: