diff options
Diffstat (limited to 'rigify/legacy/rigs/finger.py')
-rw-r--r-- | rigify/legacy/rigs/finger.py | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/rigify/legacy/rigs/finger.py b/rigify/legacy/rigs/finger.py deleted file mode 100644 index 94684606..00000000 --- a/rigify/legacy/rigs/finger.py +++ /dev/null @@ -1,408 +0,0 @@ -#====================== 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 - -import bpy -from mathutils import Vector - -from ..utils import MetarigError -from ..utils import copy_bone -from ..utils import connected_children_names -from ..utils import strip_org, make_mechanism_name, make_deformer_name -from ..utils import create_widget, create_limb_widget - -from ...utils.mechanism import make_property - -class Rig: - """ A finger rig. It takes a single chain of bones. - 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_bones = [bone] + connected_children_names(obj, bone) - self.params = params - - 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))) - - # Get user-specified layers, if they exist - if params.separate_extra_layers: - self.ex_layers = list(params.extra_layers) - else: - self.ex_layers = None - - # Get other rig parameters - self.primary_rotation_axis = params.primary_rotation_axis - self.use_digit_twist = params.use_digit_twist - - def deform(self): - """ Generate the deformation rig. - Just a copy of the original bones, except the first digit which is a twist bone. - """ - bpy.ops.object.mode_set(mode='EDIT') - - # Create the bones - # First bone is a twist bone - if self.use_digit_twist: - b1a = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".01"))) - b1b = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0] + ".02"))) - b1tip = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(self.org_bones[0] + ".tip"))) - else: - b1 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0]))) - - # The rest are normal - bones = [] - for bone in self.org_bones[1:]: - bones += [copy_bone(self.obj, bone, make_deformer_name(strip_org(bone)))] - - # Position bones - eb = self.obj.data.edit_bones - if self.use_digit_twist: - b1a_e = eb[b1a] - b1b_e = eb[b1b] - b1tip_e = eb[b1tip] - - b1tip_e.use_connect = False - b1tip_e.tail += Vector((0.1, 0, 0)) - b1tip_e.head = b1b_e.tail - b1tip_e.length = b1a_e.length / 4 - - center = (b1a_e.head + b1a_e.tail) / 2 - b1a_e.tail = center - b1b_e.use_connect = False - b1b_e.head = center - - # Parenting - if self.use_digit_twist: - b1b_e.parent = eb[self.org_bones[0]] - b1tip_e.parent = eb[self.org_bones[0]] - else: - eb[b1].use_connect = False - eb[b1].parent = eb[self.org_bones[0]] - - for (ba, bb) in zip(bones, self.org_bones[1:]): - eb[ba].use_connect = False - eb[ba].parent = eb[bb] - - # Constraints - if self.use_digit_twist: - bpy.ops.object.mode_set(mode='OBJECT') - pb = self.obj.pose.bones - - b1a_p = pb[b1a] - - con = b1a_p.constraints.new('COPY_LOCATION') - con.name = "copy_location" - con.target = self.obj - con.subtarget = self.org_bones[0] - - con = b1a_p.constraints.new('COPY_SCALE') - con.name = "copy_scale" - con.target = self.obj - con.subtarget = self.org_bones[0] - - con = b1a_p.constraints.new('DAMPED_TRACK') - con.name = "track_to" - con.target = self.obj - con.subtarget = b1tip - - def control(self): - """ Generate the control rig. - """ - bpy.ops.object.mode_set(mode='EDIT') - - # Figure out the name for the control bone (remove the last .##) - ctrl_name = re.sub("([0-9]+\.)", "", strip_org(self.org_bones[0])[::-1], count=1)[::-1] - - # Create the bones - ctrl = copy_bone(self.obj, self.org_bones[0], ctrl_name) - - helpers = [] - bones = [] - for bone in self.org_bones: - bones += [copy_bone(self.obj, bone, strip_org(bone))] - helpers += [copy_bone(self.obj, bone, make_mechanism_name(strip_org(bone)))] - - # Position bones - eb = self.obj.data.edit_bones - - length = 0.0 - for bone in helpers: - length += eb[bone].length - eb[bone].length /= 2 - - eb[ctrl].length = length * 1.5 - - # Parent bones - prev = eb[self.org_bones[0]].parent - for (b, h) in zip(bones, helpers): - b_e = eb[b] - h_e = eb[h] - b_e.use_connect = False - h_e.use_connect = False - - b_e.parent = h_e - h_e.parent = prev - - prev = b_e - - # Transform locks and rotation mode - bpy.ops.object.mode_set(mode='OBJECT') - pb = self.obj.pose.bones - - for bone in bones[1:]: - pb[bone].lock_location = True, True, True - - if pb[self.org_bones[0]].bone.use_connect is True: - pb[bones[0]].lock_location = True, True, True - - pb[ctrl].lock_scale = True, False, True - - for bone in helpers: - pb[bone].rotation_mode = 'XYZ' - - # Drivers - i = 1 - val = 1.2 / (len(self.org_bones) - 1) - for bone in helpers: - # Add custom prop - prop_name = "bend_%02d" % i - if i == 1: - propval = 0.0 - else: - propval = val - - make_property(pb[ctrl], prop_name, propval) - - # Add driver - if 'X' in self.primary_rotation_axis: - fcurve = pb[bone].driver_add("rotation_euler", 0) - elif 'Y' in self.primary_rotation_axis: - fcurve = pb[bone].driver_add("rotation_euler", 1) - else: - fcurve = pb[bone].driver_add("rotation_euler", 2) - - driver = fcurve.driver - driver.type = 'SCRIPTED' - - var = driver.variables.new() - var.name = "ctrl_y" - var.targets[0].id_type = 'OBJECT' - var.targets[0].id = self.obj - var.targets[0].data_path = pb[ctrl].path_from_id() + '.scale[1]' - - var = driver.variables.new() - var.name = "bend" - var.targets[0].id_type = 'OBJECT' - var.targets[0].id = self.obj - var.targets[0].data_path = pb[ctrl].path_from_id() + '["' + prop_name + '"]' - - if '-' in self.primary_rotation_axis: - driver.expression = "-(1.0-ctrl_y) * bend * 3.14159 * 2" - else: - driver.expression = "(1.0-ctrl_y) * bend * 3.14159 * 2" - - i += 1 - - # Constraints - con = pb[helpers[0]].constraints.new('COPY_LOCATION') - con.name = "copy_location" - con.target = self.obj - con.subtarget = ctrl - - con = pb[helpers[0]].constraints.new('COPY_ROTATION') - con.name = "copy_rotation" - con.target = self.obj - con.subtarget = ctrl - - # Constrain org bones to the control bones - for (bone, org) in zip(bones, self.org_bones): - con = pb[org].constraints.new('COPY_TRANSFORMS') - con.name = "copy_transforms" - con.target = self.obj - con.subtarget = bone - - # Set layers for extra control bones - if self.ex_layers: - for bone in bones: - pb[bone].bone.layers = self.ex_layers - - # Create control widgets - w = create_widget(self.obj, ctrl) - 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.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() - - for bone in bones: - create_limb_widget(self.obj, bone) - - 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. - """ - self.deform() - self.control() - - -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') - - params.separate_extra_layers = bpy.props.BoolProperty(name="Separate Secondary Control Layers:", default=False, description="Enable putting the secondary controls on a separate layer from the primary controls") - params.extra_layers = bpy.props.BoolVectorProperty(size=32, description="Layers for the secondary controls to be on") - - params.use_digit_twist = bpy.props.BoolProperty(name="Digit Twist", default=True, description="Generate the dual-bone twist setup for the first finger digit") - - -def parameters_ui(layout, params): - """ Create the ui for the rig parameters. - """ - r = layout.row() - r.prop(params, "separate_extra_layers") - - r = layout.row() - r.active = params.separate_extra_layers - - col = r.column(align=True) - row = col.row(align=True) - row.prop(params, "extra_layers", index=0, toggle=True, text="") - row.prop(params, "extra_layers", index=1, toggle=True, text="") - row.prop(params, "extra_layers", index=2, toggle=True, text="") - row.prop(params, "extra_layers", index=3, toggle=True, text="") - row.prop(params, "extra_layers", index=4, toggle=True, text="") - row.prop(params, "extra_layers", index=5, toggle=True, text="") - row.prop(params, "extra_layers", index=6, toggle=True, text="") - row.prop(params, "extra_layers", index=7, toggle=True, text="") - row = col.row(align=True) - row.prop(params, "extra_layers", index=16, toggle=True, text="") - row.prop(params, "extra_layers", index=17, toggle=True, text="") - row.prop(params, "extra_layers", index=18, toggle=True, text="") - row.prop(params, "extra_layers", index=19, toggle=True, text="") - row.prop(params, "extra_layers", index=20, toggle=True, text="") - row.prop(params, "extra_layers", index=21, toggle=True, text="") - row.prop(params, "extra_layers", index=22, toggle=True, text="") - row.prop(params, "extra_layers", index=23, toggle=True, text="") - - col = r.column(align=True) - row = col.row(align=True) - row.prop(params, "extra_layers", index=8, toggle=True, text="") - row.prop(params, "extra_layers", index=9, toggle=True, text="") - row.prop(params, "extra_layers", index=10, toggle=True, text="") - row.prop(params, "extra_layers", index=11, toggle=True, text="") - row.prop(params, "extra_layers", index=12, toggle=True, text="") - row.prop(params, "extra_layers", index=13, toggle=True, text="") - row.prop(params, "extra_layers", index=14, toggle=True, text="") - row.prop(params, "extra_layers", index=15, toggle=True, text="") - row = col.row(align=True) - row.prop(params, "extra_layers", index=24, toggle=True, text="") - row.prop(params, "extra_layers", index=25, toggle=True, text="") - row.prop(params, "extra_layers", index=26, toggle=True, text="") - row.prop(params, "extra_layers", index=27, toggle=True, text="") - row.prop(params, "extra_layers", index=28, toggle=True, text="") - row.prop(params, "extra_layers", index=29, toggle=True, text="") - row.prop(params, "extra_layers", index=30, toggle=True, text="") - row.prop(params, "extra_layers", index=31, toggle=True, text="") - - r = layout.row() - r.label(text="Bend rotation axis:") - r.prop(params, "primary_rotation_axis", text="") - - col = layout.column() - col.prop(params, "use_digit_twist") - - -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('finger.01') - bone.head[:] = 0.0000, 0.0000, 0.0000 - bone.tail[:] = 0.2529, 0.0000, 0.0000 - bone.roll = 3.1416 - bone.use_connect = False - bones['finger.01'] = bone.name - bone = arm.edit_bones.new('finger.02') - bone.head[:] = 0.2529, 0.0000, 0.0000 - bone.tail[:] = 0.4024, 0.0000, -0.0264 - bone.roll = -2.9671 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['finger.01']] - bones['finger.02'] = bone.name - bone = arm.edit_bones.new('finger.03') - bone.head[:] = 0.4024, 0.0000, -0.0264 - bone.tail[:] = 0.4975, -0.0000, -0.0610 - bone.roll = -2.7925 - bone.use_connect = True - bone.parent = arm.edit_bones[bones['finger.02']] - bones['finger.03'] = bone.name - - bpy.ops.object.mode_set(mode='OBJECT') - pbone = obj.pose.bones[bones['finger.01']] - 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 = 'YZX' - pbone = obj.pose.bones[bones['finger.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 = 'YZX' - pbone = obj.pose.bones[bones['finger.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 = 'YZX' - - 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 |