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

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucio Rossi <lucio.rossi75@gmail.com>2017-05-14 19:30:06 +0300
committerLucio Rossi <lucio.rossi75@gmail.com>2017-05-14 19:30:06 +0300
commitf36789d8bc728bc7ec3c9738f1ca76e8f017ce7a (patch)
treeb21bf3b259ee87b4eafb1503936b15bee38be1ca /rigify/rigs
parent8e68bf2879d81780e51dbdc3481bb486e7430e74 (diff)
Rigify 0.5 with legacy mode
Diffstat (limited to 'rigify/rigs')
-rw-r--r--rigify/rigs/basic/copy.py139
-rw-r--r--rigify/rigs/basic/super_copy.py (renamed from rigify/rigs/pitchipoy/super_copy.py)32
-rw-r--r--rigify/rigs/biped/arm/__init__.py306
-rw-r--r--rigify/rigs/biped/arm/deform.py58
-rw-r--r--rigify/rigs/biped/arm/fk.py86
-rw-r--r--rigify/rigs/biped/arm/ik.py90
-rw-r--r--rigify/rigs/biped/leg/__init__.py345
-rw-r--r--rigify/rigs/biped/leg/deform.py92
-rw-r--r--rigify/rigs/biped/leg/fk.py130
-rw-r--r--rigify/rigs/biped/leg/ik.py350
-rw-r--r--rigify/rigs/biped/limb_common.py1287
-rw-r--r--rigify/rigs/experimental/__init__.py (renamed from rigify/rigs/biped/__init__.py)0
-rw-r--r--rigify/rigs/experimental/super_chain.py1414
-rw-r--r--rigify/rigs/experimental/super_eye.py (renamed from rigify/rigs/pitchipoy/__init__.py)0
-rw-r--r--rigify/rigs/faces/__init__.py (renamed from rigify/rigs/pitchipoy/limbs/__init__.py)0
-rw-r--r--[-rwxr-xr-x]rigify/rigs/faces/super_face.py (renamed from rigify/rigs/pitchipoy/super_face.py)408
-rw-r--r--rigify/rigs/finger.py411
-rw-r--r--rigify/rigs/limbs/__init__.py0
-rw-r--r--rigify/rigs/limbs/arm.py (renamed from rigify/rigs/pitchipoy/limbs/super_arm.py)638
-rw-r--r--rigify/rigs/limbs/leg.py (renamed from rigify/rigs/pitchipoy/limbs/super_leg.py)675
-rw-r--r--rigify/rigs/limbs/limb_utils.py (renamed from rigify/rigs/pitchipoy/limbs/limb_utils.py)18
-rw-r--r--rigify/rigs/limbs/paw.py (renamed from rigify/rigs/pitchipoy/limbs/super_front_paw.py)646
-rw-r--r--rigify/rigs/limbs/rear_paw.py319
-rw-r--r--rigify/rigs/limbs/simple_tentacle.py (renamed from rigify/rigs/pitchipoy/simple_tentacle.py)147
-rw-r--r--rigify/rigs/limbs/super_finger.py (renamed from rigify/rigs/pitchipoy/super_finger.py)118
-rw-r--r--rigify/rigs/limbs/super_limb.py243
-rw-r--r--[-rwxr-xr-x]rigify/rigs/limbs/super_palm.py (renamed from rigify/rigs/pitchipoy/super_palm.py)10
-rw-r--r--rigify/rigs/limbs/ui.py (renamed from rigify/rigs/pitchipoy/limbs/ui.py)67
-rw-r--r--rigify/rigs/neck_short.py388
-rw-r--r--rigify/rigs/palm.py273
-rw-r--r--rigify/rigs/pitchipoy/limbs/arm.py116
-rw-r--r--rigify/rigs/pitchipoy/limbs/leg.py333
-rw-r--r--rigify/rigs/pitchipoy/limbs/paw.py214
-rw-r--r--rigify/rigs/pitchipoy/limbs/super_limb.py783
-rw-r--r--rigify/rigs/pitchipoy/limbs/super_rear_paw.py1261
-rw-r--r--rigify/rigs/pitchipoy/super_torso_turbo.py911
-rw-r--r--rigify/rigs/pitchipoy/tentacle.py509
-rw-r--r--rigify/rigs/spine.py567
-rw-r--r--rigify/rigs/spines/__init__.py0
-rw-r--r--rigify/rigs/spines/super_spine.py1249
-rw-r--r--rigify/rigs/widgets.py (renamed from rigify/rigs/pitchipoy/super_widgets.py)33
41 files changed, 4970 insertions, 9696 deletions
diff --git a/rigify/rigs/basic/copy.py b/rigify/rigs/basic/copy.py
deleted file mode 100644
index 50a25767..00000000
--- a/rigify/rigs/basic/copy.py
+++ /dev/null
@@ -1,139 +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 bpy
-
-from ...utils import copy_bone
-from ...utils import strip_org, make_deformer_name
-from ...utils import create_bone_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_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
- 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_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_deform")
-
-
-def create_sample(obj):
- """ Create a sample metarig for this rig type.
- """
- # generated by rigify.utils.write_metarig
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
-
- bones = {}
-
- bone = arm.edit_bones.new('Bone')
- bone.head[:] = 0.0000, 0.0000, 0.0000
- bone.tail[:] = 0.0000, 0.0000, 0.2000
- bone.roll = 0.0000
- bone.use_connect = False
- bones['Bone'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
- pbone = obj.pose.bones[bones['Bone']]
- pbone.rigify_type = 'basic.copy'
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
-
- bpy.ops.object.mode_set(mode='EDIT')
- for bone in arm.edit_bones:
- bone.select = False
- bone.select_head = False
- bone.select_tail = False
- for b in bones:
- bone = arm.edit_bones[bones[b]]
- bone.select = True
- bone.select_head = True
- bone.select_tail = True
- arm.edit_bones.active = bone
diff --git a/rigify/rigs/pitchipoy/super_copy.py b/rigify/rigs/basic/super_copy.py
index 27e88775..cd0f144f 100644
--- a/rigify/rigs/pitchipoy/super_copy.py
+++ b/rigify/rigs/basic/super_copy.py
@@ -83,30 +83,31 @@ class Rig:
# Create control widget
if self.make_widget:
- create_circle_widget(self.obj, bone, radius = 0.5 )
+ create_circle_widget(self.obj, bone, radius=0.5)
else:
- create_bone_widget(self.obj, bone, radius = 0.5 )
+ 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_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"
)
@@ -117,6 +118,7 @@ def parameters_ui(layout, params):
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")
@@ -139,7 +141,7 @@ def create_sample(obj):
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones[bones['Bone']]
- pbone.rigify_type = 'basic.copy'
+ pbone.rigify_type = 'basic.super_copy'
pbone.lock_location = (False, False, False)
pbone.lock_rotation = (False, False, False)
pbone.lock_rotation_w = False
diff --git a/rigify/rigs/biped/arm/__init__.py b/rigify/rigs/biped/arm/__init__.py
deleted file mode 100644
index e418a45a..00000000
--- a/rigify/rigs/biped/arm/__init__.py
+++ /dev/null
@@ -1,306 +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 bpy
-import importlib
-from . import fk, ik, deform
-
-importlib.reload(fk)
-importlib.reload(ik)
-importlib.reload(deform)
-
-script = """
-fk_arm = ["%s", "%s", "%s"]
-ik_arm = ["%s", "%s", "%s", "%s"]
-if is_selected(fk_arm+ik_arm):
- layout.prop(pose_bones[ik_arm[2]], '["ikfk_switch"]', text="FK / IK (" + ik_arm[2] + ")", slider=True)
- props = layout.operator("pose.rigify_arm_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_arm[0] + ")")
- props.uarm_fk = fk_arm[0]
- props.farm_fk = fk_arm[1]
- props.hand_fk = fk_arm[2]
- props.uarm_ik = ik_arm[0]
- props.farm_ik = ik_arm[1]
- props.hand_ik = ik_arm[2]
- props = layout.operator("pose.rigify_arm_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_arm[0] + ")")
- props.uarm_fk = fk_arm[0]
- props.farm_fk = fk_arm[1]
- props.hand_fk = fk_arm[2]
- props.uarm_ik = ik_arm[0]
- props.farm_ik = ik_arm[1]
- props.hand_ik = ik_arm[2]
- props.pole = ik_arm[3]
-if is_selected(fk_arm):
- try:
- pose_bones[fk_arm[0]]["isolate"]
- layout.prop(pose_bones[fk_arm[0]], '["isolate"]', text="Isolate Rotation (" + fk_arm[0] + ")", slider=True)
- except KeyError:
- pass
- layout.prop(pose_bones[fk_arm[0]], '["stretch_length"]', text="Length FK (" + fk_arm[0] + ")", slider=True)
-if is_selected(ik_arm):
- layout.prop(pose_bones[ik_arm[2]], '["stretch_length"]', text="Length IK (" + ik_arm[2] + ")", slider=True)
- layout.prop(pose_bones[ik_arm[2]], '["auto_stretch"]', text="Auto-Stretch IK (" + ik_arm[2] + ")", slider=True)
-if is_selected([ik_arm[3]]):
- layout.prop(pose_bones[ik_arm[3]], '["follow"]', text="Follow Parent (" + ik_arm[3] + ")", slider=True)
-"""
-
-hose_script = """
-hose_arm = ["%s", "%s", "%s", "%s", "%s"]
-if is_selected(hose_arm):
- layout.prop(pose_bones[hose_arm[2]], '["smooth_bend"]', text="Smooth Elbow (" + hose_arm[2] + ")", slider=True)
-"""
-
-end_script = """
-if is_selected(fk_arm+ik_arm):
- layout.separator()
-"""
-
-
-class Rig:
- """ An arm rig, with IK/FK switching and hinge switch.
-
- """
- 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 names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
-
- """
- self.obj = obj
- self.params = params
-
- # Gather deform rig
- self.deform_rig = deform.Rig(obj, bone, params)
-
- # Gather FK rig
- self.fk_rig = fk.Rig(obj, bone, params)
-
- # Gather IK rig
- self.ik_rig = ik.Rig(obj, bone, params, ikfk_switch=True)
-
- 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.
-
- """
- hose_controls = self.deform_rig.generate()
- fk_controls = self.fk_rig.generate()
- ik_controls = self.ik_rig.generate()
- ui_script = script % (fk_controls[0], fk_controls[1], fk_controls[2], ik_controls[0], ik_controls[1], ik_controls[2], ik_controls[3])
- if self.params.use_complex_arm:
- ui_script += hose_script % (hose_controls[0], hose_controls[1], hose_controls[2], hose_controls[3], hose_controls[4])
- ui_script += end_script
- return [ui_script]
-
-
-def add_parameters(params):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
-
- """
- params.use_complex_arm = bpy.props.BoolProperty(name="Complex Arm Rig", default=True, description="Generate the full, complex arm rig with twist bones and rubber-hose controls")
- params.bend_hint = bpy.props.BoolProperty(name="Bend Hint", default=True, description="Give IK chain a hint about which way to bend. Useful for perfectly straight chains")
-
- 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.elbow_base_name = bpy.props.StringProperty(name="Elbow Name", default="elbow", description="Base name for the generated elbow-related controls")
-
- params.separate_ik_layers = bpy.props.BoolProperty(name="Separate IK Control Layers:", default=False, description="Enable putting the ik controls on a separate layer from the fk controls")
- params.ik_layers = bpy.props.BoolVectorProperty(size=32, description="Layers for the ik controls to be on")
-
- params.separate_hose_layers = bpy.props.BoolProperty(name="Separate Rubber-hose Control Layers:", default=False, description="Enable putting the rubber-hose controls on a separate layer from the other controls")
- params.hose_layers = bpy.props.BoolVectorProperty(size=32, description="Layers for the rubber-hose controls to be on")
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters.
-
- """
- col = layout.column()
- col.prop(params, "use_complex_arm")
-
- r = layout.row()
- r.label(text="Elbow rotation axis:")
- r.prop(params, "primary_rotation_axis", text="")
-
- r = layout.row()
- r.prop(params, "elbow_base_name")
-
- r = layout.row()
- r.prop(params, "bend_hint")
-
- r = layout.row()
- r.prop(params, "separate_ik_layers")
-
- r = layout.row()
- r.active = params.separate_ik_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=0, toggle=True, text="")
- row.prop(params, "ik_layers", index=1, toggle=True, text="")
- row.prop(params, "ik_layers", index=2, toggle=True, text="")
- row.prop(params, "ik_layers", index=3, toggle=True, text="")
- row.prop(params, "ik_layers", index=4, toggle=True, text="")
- row.prop(params, "ik_layers", index=5, toggle=True, text="")
- row.prop(params, "ik_layers", index=6, toggle=True, text="")
- row.prop(params, "ik_layers", index=7, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=16, toggle=True, text="")
- row.prop(params, "ik_layers", index=17, toggle=True, text="")
- row.prop(params, "ik_layers", index=18, toggle=True, text="")
- row.prop(params, "ik_layers", index=19, toggle=True, text="")
- row.prop(params, "ik_layers", index=20, toggle=True, text="")
- row.prop(params, "ik_layers", index=21, toggle=True, text="")
- row.prop(params, "ik_layers", index=22, toggle=True, text="")
- row.prop(params, "ik_layers", index=23, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=8, toggle=True, text="")
- row.prop(params, "ik_layers", index=9, toggle=True, text="")
- row.prop(params, "ik_layers", index=10, toggle=True, text="")
- row.prop(params, "ik_layers", index=11, toggle=True, text="")
- row.prop(params, "ik_layers", index=12, toggle=True, text="")
- row.prop(params, "ik_layers", index=13, toggle=True, text="")
- row.prop(params, "ik_layers", index=14, toggle=True, text="")
- row.prop(params, "ik_layers", index=15, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=24, toggle=True, text="")
- row.prop(params, "ik_layers", index=25, toggle=True, text="")
- row.prop(params, "ik_layers", index=26, toggle=True, text="")
- row.prop(params, "ik_layers", index=27, toggle=True, text="")
- row.prop(params, "ik_layers", index=28, toggle=True, text="")
- row.prop(params, "ik_layers", index=29, toggle=True, text="")
- row.prop(params, "ik_layers", index=30, toggle=True, text="")
- row.prop(params, "ik_layers", index=31, toggle=True, text="")
-
- if params.use_complex_arm:
- r = layout.row()
- r.prop(params, "separate_hose_layers")
-
- r = layout.row()
- r.active = params.separate_hose_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=0, toggle=True, text="")
- row.prop(params, "hose_layers", index=1, toggle=True, text="")
- row.prop(params, "hose_layers", index=2, toggle=True, text="")
- row.prop(params, "hose_layers", index=3, toggle=True, text="")
- row.prop(params, "hose_layers", index=4, toggle=True, text="")
- row.prop(params, "hose_layers", index=5, toggle=True, text="")
- row.prop(params, "hose_layers", index=6, toggle=True, text="")
- row.prop(params, "hose_layers", index=7, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=16, toggle=True, text="")
- row.prop(params, "hose_layers", index=17, toggle=True, text="")
- row.prop(params, "hose_layers", index=18, toggle=True, text="")
- row.prop(params, "hose_layers", index=19, toggle=True, text="")
- row.prop(params, "hose_layers", index=20, toggle=True, text="")
- row.prop(params, "hose_layers", index=21, toggle=True, text="")
- row.prop(params, "hose_layers", index=22, toggle=True, text="")
- row.prop(params, "hose_layers", index=23, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=8, toggle=True, text="")
- row.prop(params, "hose_layers", index=9, toggle=True, text="")
- row.prop(params, "hose_layers", index=10, toggle=True, text="")
- row.prop(params, "hose_layers", index=11, toggle=True, text="")
- row.prop(params, "hose_layers", index=12, toggle=True, text="")
- row.prop(params, "hose_layers", index=13, toggle=True, text="")
- row.prop(params, "hose_layers", index=14, toggle=True, text="")
- row.prop(params, "hose_layers", index=15, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=24, toggle=True, text="")
- row.prop(params, "hose_layers", index=25, toggle=True, text="")
- row.prop(params, "hose_layers", index=26, toggle=True, text="")
- row.prop(params, "hose_layers", index=27, toggle=True, text="")
- row.prop(params, "hose_layers", index=28, toggle=True, text="")
- row.prop(params, "hose_layers", index=29, toggle=True, text="")
- row.prop(params, "hose_layers", index=30, toggle=True, text="")
- row.prop(params, "hose_layers", index=31, toggle=True, text="")
-
-
-def create_sample(obj):
- # generated by rigify.utils.write_meta_rig
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
-
- bones = {}
-
- bone = arm.edit_bones.new('upper_arm')
- bone.head[:] = 0.0000, 0.0000, 0.0000
- bone.tail[:] = 0.3000, 0.0300, 0.0000
- bone.roll = 1.5708
- bone.use_connect = False
- bones['upper_arm'] = bone.name
- bone = arm.edit_bones.new('forearm')
- bone.head[:] = 0.3000, 0.0300, 0.0000
- bone.tail[:] = 0.6000, 0.0000, 0.0000
- bone.roll = 1.5708
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['upper_arm']]
- bones['forearm'] = bone.name
- bone = arm.edit_bones.new('hand')
- bone.head[:] = 0.6000, 0.0000, 0.0000
- bone.tail[:] = 0.7000, 0.0000, 0.0000
- bone.roll = 3.1416
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['forearm']]
- bones['hand'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
- pbone = obj.pose.bones[bones['upper_arm']]
- 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 = obj.pose.bones[bones['forearm']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, 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']]
- pbone.rigify_type = ''
- pbone.lock_location = (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/biped/arm/deform.py b/rigify/rigs/biped/arm/deform.py
deleted file mode 100644
index a5444207..00000000
--- a/rigify/rigs/biped/arm/deform.py
+++ /dev/null
@@ -1,58 +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 bpy
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import connected_children_names
-from ....utils import strip_org
-
-
-class Rig:
- """ An FK arm rig, with hinge switch.
-
- """
- def __init__(self, obj, bone, params):
- self.obj = obj
- self.params = params
-
- # Get the chain of 3 connected bones
- self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]
-
- if len(self.org_bones) != 3:
- raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones" % (strip_org(bone)))
-
- # Get rig parameters
- if params.separate_hose_layers:
- layers = list(params.hose_layers)
- else:
- layers = None
- use_complex_rig = params.use_complex_arm
- elbow_base_name = params.elbow_base_name
- primary_rotation_axis = params.primary_rotation_axis
-
- # Based on common limb
- self.rubber_hose_limb = limb_common.RubberHoseLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], use_complex_rig, elbow_base_name, primary_rotation_axis, layers)
-
- def generate(self):
- bone_list = self.rubber_hose_limb.generate()
- return bone_list
diff --git a/rigify/rigs/biped/arm/fk.py b/rigify/rigs/biped/arm/fk.py
deleted file mode 100644
index 03ff6fc9..00000000
--- a/rigify/rigs/biped/arm/fk.py
+++ /dev/null
@@ -1,86 +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 bpy
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import connected_children_names
-from ....utils import create_widget
-from ....utils import strip_org
-from ....utils import get_layers
-
-
-class Rig:
- """ An FK arm rig, with hinge switch.
-
- """
- 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, and
- store names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
-
- """
- self.obj = obj
-
- # Get the chain of 3 connected bones
- self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]
-
- if len(self.org_bones) != 3:
- raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of at least 3 bones" % (strip_org(bone)))
-
- # Get params
- if "layers" in params:
- layers = get_layers(params["layers"])
- else:
- layers = None
-
- primary_rotation_axis = params.primary_rotation_axis
-
- # Arm is based on common limb
- self.fk_limb = limb_common.FKLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], primary_rotation_axis, layers)
-
- 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.
-
- """
- bone_list = self.fk_limb.generate()
- uarm = bone_list[0]
- farm = bone_list[1]
- hand = bone_list[2]
-
- # Create hand widget
- ob = create_widget(self.obj, hand)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [uarm, farm, hand]
diff --git a/rigify/rigs/biped/arm/ik.py b/rigify/rigs/biped/arm/ik.py
deleted file mode 100644
index e4cd2b5d..00000000
--- a/rigify/rigs/biped/arm/ik.py
+++ /dev/null
@@ -1,90 +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 bpy
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import connected_children_names
-from ....utils import strip_org
-from ....utils import create_widget
-
-
-class Rig:
- """ An IK arm rig, with an optional ik/fk switch.
-
- """
- def __init__(self, obj, bone, params, ikfk_switch=False):
- """ 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, and
- store names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
-
- ikfk_switch: if True, create an ik/fk switch slider
- """
- self.obj = obj
- self.params = params
-
- # Get the chain of 3 connected bones
- self.org_bones = [bone] + connected_children_names(self.obj, bone)[:2]
- if len(self.org_bones) != 3:
- raise MetarigError("RIGIFY ERROR: Bone '%s': input to rig type must be a chain of 3 bones" % (strip_org(bone)))
-
- # Get the rig parameters
- if params.separate_ik_layers:
- layers = list(params.ik_layers)
- else:
- layers = None
- bend_hint = params.bend_hint
- primary_rotation_axis = params.primary_rotation_axis
- pole_target_base_name = self.params.elbow_base_name + "_target"
-
- # Arm is based on common limb
- self.ik_limb = limb_common.IKLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], None, pole_target_base_name, primary_rotation_axis, bend_hint, layers, ikfk_switch)
-
- 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.
-
- """
- bone_list = self.ik_limb.generate()
- uarm = bone_list[0]
- farm = bone_list[1]
- hand = bone_list[2]
- # hand_mch = bone_list[3]
- pole = bone_list[4]
- # vispole = bone_list[5]
- # vishand = bone_list[6]
-
- ob = create_widget(self.obj, hand)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [uarm, farm, hand, pole]
diff --git a/rigify/rigs/biped/leg/__init__.py b/rigify/rigs/biped/leg/__init__.py
deleted file mode 100644
index 97241ead..00000000
--- a/rigify/rigs/biped/leg/__init__.py
+++ /dev/null
@@ -1,345 +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 bpy
-import importlib
-from . import fk, ik, deform
-
-importlib.reload(fk)
-importlib.reload(ik)
-importlib.reload(deform)
-
-script = """
-fk_leg = ["%s", "%s", "%s", "%s"]
-ik_leg = ["%s", "%s", "%s", "%s", "%s", "%s"]
-if is_selected(fk_leg+ik_leg):
- layout.prop(pose_bones[ik_leg[2]], '["ikfk_switch"]', text="FK / IK (" + ik_leg[2] + ")", slider=True)
- p = layout.operator("pose.rigify_leg_fk2ik_" + rig_id, text="Snap FK->IK (" + fk_leg[0] + ")")
- p.thigh_fk = fk_leg[0]
- p.shin_fk = fk_leg[1]
- p.foot_fk = fk_leg[2]
- p.mfoot_fk = fk_leg[3]
- p.thigh_ik = ik_leg[0]
- p.shin_ik = ik_leg[1]
- p.foot_ik = ik_leg[2]
- p.mfoot_ik = ik_leg[5]
- p = layout.operator("pose.rigify_leg_ik2fk_" + rig_id, text="Snap IK->FK (" + fk_leg[0] + ")")
- p.thigh_fk = fk_leg[0]
- p.shin_fk = fk_leg[1]
- p.mfoot_fk = fk_leg[3]
- p.thigh_ik = ik_leg[0]
- p.shin_ik = ik_leg[1]
- p.foot_ik = ik_leg[2]
- p.pole = ik_leg[3]
- p.footroll = ik_leg[4]
- p.mfoot_ik = ik_leg[5]
-if is_selected(fk_leg):
- try:
- pose_bones[fk_leg[0]]["isolate"]
- layout.prop(pose_bones[fk_leg[0]], '["isolate"]', text="Isolate Rotation (" + fk_leg[0] + ")", slider=True)
- except KeyError:
- pass
- layout.prop(pose_bones[fk_leg[0]], '["stretch_length"]', text="Length FK (" + fk_leg[0] + ")", slider=True)
-if is_selected(ik_leg):
- layout.prop(pose_bones[ik_leg[2]], '["stretch_length"]', text="Length IK (" + ik_leg[2] + ")", slider=True)
- layout.prop(pose_bones[ik_leg[2]], '["auto_stretch"]', text="Auto-Stretch IK (" + ik_leg[2] + ")", slider=True)
-if is_selected([ik_leg[3]]):
- layout.prop(pose_bones[ik_leg[3]], '["follow"]', text="Follow Foot (" + ik_leg[3] + ")", slider=True)
-"""
-
-hose_script = """
-hose_leg = ["%s", "%s", "%s", "%s", "%s"]
-if is_selected(hose_leg):
- layout.prop(pose_bones[hose_leg[2]], '["smooth_bend"]', text="Smooth Knee (" + hose_leg[2] + ")", slider=True)
-"""
-
-end_script = """
-if is_selected(fk_leg+ik_leg):
- layout.separator()
-"""
-
-
-class Rig:
- """ A leg rig, with IK/FK switching, a hinge switch, and foot roll.
-
- """
- 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 names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
-
- """
- self.obj = obj
- self.params = params
-
- # Gather deform rig
- self.deform_rig = deform.Rig(obj, bone, params)
-
- # Gather FK rig
- self.fk_rig = fk.Rig(obj, bone, params)
-
- # Gather IK rig
- self.ik_rig = ik.Rig(obj, bone, params, ikfk_switch=True)
-
- 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.
-
- """
- hose_controls = self.deform_rig.generate()
- fk_controls = self.fk_rig.generate()
- ik_controls = self.ik_rig.generate()
- ui_script = script % (fk_controls[0], fk_controls[1], fk_controls[2], fk_controls[3], ik_controls[0], ik_controls[1], ik_controls[2], ik_controls[3], ik_controls[4], ik_controls[5])
- if self.params.use_complex_leg:
- ui_script += hose_script % (hose_controls[0], hose_controls[1], hose_controls[2], hose_controls[3], hose_controls[4])
- ui_script += end_script
- return [ui_script]
-
-
-def add_parameters(params):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
-
- """
- params.use_complex_leg = bpy.props.BoolProperty(name="Complex Leg Rig", default=True, description="Generate the full, complex leg rig with twist bones and rubber-hose controls")
- params.bend_hint = bpy.props.BoolProperty(name="Bend Hint", default=True, description="Give IK chain a hint about which way to bend (useful for perfectly straight chains)")
-
- 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.knee_base_name = bpy.props.StringProperty(name="Knee Name", default="knee", description="Base name for the generated knee-related controls")
-
- params.separate_ik_layers = bpy.props.BoolProperty(name="Separate IK Control Layers:", default=False, description="Enable putting the ik controls on a separate layer from the fk controls")
- params.ik_layers = bpy.props.BoolVectorProperty(size=32, description="Layers for the ik controls to be on")
-
- params.separate_hose_layers = bpy.props.BoolProperty(name="Separate Rubber-hose Control Layers:", default=False, description="Enable putting the rubber-hose controls on a separate layer from the other controls")
- params.hose_layers = bpy.props.BoolVectorProperty(size=32, description="Layers for the rubber-hose controls to be on")
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters.
-
- """
- col = layout.column()
- col.prop(params, "use_complex_leg")
-
- r = layout.row()
- r.label(text="Knee rotation axis:")
- r.prop(params, "primary_rotation_axis", text="")
-
- r = layout.row()
- r.prop(params, "knee_base_name")
-
- r = layout.row()
- r.prop(params, "bend_hint")
-
- r = layout.row()
- r.prop(params, "separate_ik_layers")
-
- r = layout.row()
- r.active = params.separate_ik_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=0, toggle=True, text="")
- row.prop(params, "ik_layers", index=1, toggle=True, text="")
- row.prop(params, "ik_layers", index=2, toggle=True, text="")
- row.prop(params, "ik_layers", index=3, toggle=True, text="")
- row.prop(params, "ik_layers", index=4, toggle=True, text="")
- row.prop(params, "ik_layers", index=5, toggle=True, text="")
- row.prop(params, "ik_layers", index=6, toggle=True, text="")
- row.prop(params, "ik_layers", index=7, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=16, toggle=True, text="")
- row.prop(params, "ik_layers", index=17, toggle=True, text="")
- row.prop(params, "ik_layers", index=18, toggle=True, text="")
- row.prop(params, "ik_layers", index=19, toggle=True, text="")
- row.prop(params, "ik_layers", index=20, toggle=True, text="")
- row.prop(params, "ik_layers", index=21, toggle=True, text="")
- row.prop(params, "ik_layers", index=22, toggle=True, text="")
- row.prop(params, "ik_layers", index=23, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=8, toggle=True, text="")
- row.prop(params, "ik_layers", index=9, toggle=True, text="")
- row.prop(params, "ik_layers", index=10, toggle=True, text="")
- row.prop(params, "ik_layers", index=11, toggle=True, text="")
- row.prop(params, "ik_layers", index=12, toggle=True, text="")
- row.prop(params, "ik_layers", index=13, toggle=True, text="")
- row.prop(params, "ik_layers", index=14, toggle=True, text="")
- row.prop(params, "ik_layers", index=15, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "ik_layers", index=24, toggle=True, text="")
- row.prop(params, "ik_layers", index=25, toggle=True, text="")
- row.prop(params, "ik_layers", index=26, toggle=True, text="")
- row.prop(params, "ik_layers", index=27, toggle=True, text="")
- row.prop(params, "ik_layers", index=28, toggle=True, text="")
- row.prop(params, "ik_layers", index=29, toggle=True, text="")
- row.prop(params, "ik_layers", index=30, toggle=True, text="")
- row.prop(params, "ik_layers", index=31, toggle=True, text="")
-
- if params.use_complex_leg:
- r = layout.row()
- r.prop(params, "separate_hose_layers")
-
- r = layout.row()
- r.active = params.separate_hose_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=0, toggle=True, text="")
- row.prop(params, "hose_layers", index=1, toggle=True, text="")
- row.prop(params, "hose_layers", index=2, toggle=True, text="")
- row.prop(params, "hose_layers", index=3, toggle=True, text="")
- row.prop(params, "hose_layers", index=4, toggle=True, text="")
- row.prop(params, "hose_layers", index=5, toggle=True, text="")
- row.prop(params, "hose_layers", index=6, toggle=True, text="")
- row.prop(params, "hose_layers", index=7, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=16, toggle=True, text="")
- row.prop(params, "hose_layers", index=17, toggle=True, text="")
- row.prop(params, "hose_layers", index=18, toggle=True, text="")
- row.prop(params, "hose_layers", index=19, toggle=True, text="")
- row.prop(params, "hose_layers", index=20, toggle=True, text="")
- row.prop(params, "hose_layers", index=21, toggle=True, text="")
- row.prop(params, "hose_layers", index=22, toggle=True, text="")
- row.prop(params, "hose_layers", index=23, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=8, toggle=True, text="")
- row.prop(params, "hose_layers", index=9, toggle=True, text="")
- row.prop(params, "hose_layers", index=10, toggle=True, text="")
- row.prop(params, "hose_layers", index=11, toggle=True, text="")
- row.prop(params, "hose_layers", index=12, toggle=True, text="")
- row.prop(params, "hose_layers", index=13, toggle=True, text="")
- row.prop(params, "hose_layers", index=14, toggle=True, text="")
- row.prop(params, "hose_layers", index=15, toggle=True, text="")
- row = col.row(align=True)
- row.prop(params, "hose_layers", index=24, toggle=True, text="")
- row.prop(params, "hose_layers", index=25, toggle=True, text="")
- row.prop(params, "hose_layers", index=26, toggle=True, text="")
- row.prop(params, "hose_layers", index=27, toggle=True, text="")
- row.prop(params, "hose_layers", index=28, toggle=True, text="")
- row.prop(params, "hose_layers", index=29, toggle=True, text="")
- row.prop(params, "hose_layers", index=30, toggle=True, text="")
- row.prop(params, "hose_layers", index=31, toggle=True, text="")
-
-
-def create_sample(obj):
- # generated by rigify.utils.write_meta_rig
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
-
- bones = {}
-
- bone = arm.edit_bones.new('thigh')
- bone.head[:] = -0.0000, 0.0000, 1.0000
- bone.tail[:] = -0.0000, -0.0500, 0.5000
- bone.roll = -0.0000
- bone.use_connect = False
- bones['thigh'] = bone.name
- bone = arm.edit_bones.new('shin')
- bone.head[:] = -0.0000, -0.0500, 0.5000
- bone.tail[:] = -0.0000, 0.0000, 0.1000
- bone.roll = -0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['thigh']]
- bones['shin'] = bone.name
- bone = arm.edit_bones.new('foot')
- bone.head[:] = -0.0000, 0.0000, 0.1000
- bone.tail[:] = 0.0000, -0.1200, 0.0300
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['shin']]
- bones['foot'] = bone.name
- bone = arm.edit_bones.new('heel')
- bone.head[:] = -0.0000, 0.0000, 0.1000
- bone.tail[:] = -0.0000, 0.0600, 0.0000
- bone.roll = -0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['shin']]
- bones['heel'] = bone.name
- bone = arm.edit_bones.new('heel.02')
- bone.head[:] = -0.0500, -0.0200, 0.0000
- bone.tail[:] = 0.0500, -0.0200, 0.0000
- bone.roll = 0.0000
- bone.use_connect = False
- bone.parent = arm.edit_bones[bones['heel']]
- bones['heel.02'] = bone.name
- bone = arm.edit_bones.new('toe')
- bone.head[:] = 0.0000, -0.1200, 0.0300
- bone.tail[:] = 0.0000, -0.2000, 0.0300
- bone.roll = 3.1416
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['foot']]
- bones['toe'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
- pbone = obj.pose.bones[bones['thigh']]
- 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 = obj.pose.bones[bones['shin']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, 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']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, 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['heel']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, 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['toe']]
- pbone.rigify_type = ''
- pbone.lock_location = (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/biped/leg/deform.py b/rigify/rigs/biped/leg/deform.py
deleted file mode 100644
index cde73250..00000000
--- a/rigify/rigs/biped/leg/deform.py
+++ /dev/null
@@ -1,92 +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 bpy
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import copy_bone
-from ....utils import connected_children_names, has_connected_children
-from ....utils import strip_org, make_deformer_name
-
-
-class Rig:
- """ A leg deform-bone setup.
-
- """
- def __init__(self, obj, bone, params):
- self.obj = obj
- self.params = params
-
- # Get the chain of 2 connected bones
- leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]
-
- if len(leg_bones) != 2:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- leg bones != 2" % (strip_org(bone)))
-
- # Get the foot and heel
- foot = None
- heel = None
- for b in self.obj.data.bones[leg_bones[1]].children:
- if b.use_connect is True:
- if len(b.children) >= 1 and has_connected_children(b):
- foot = b.name
- else:
- heel = b.name
-
- if foot is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- could not find foot bone (that is, a bone with >1 children connected) attached to bone '%s'" % (strip_org(bone), strip_org(leg_bones[1])))
- if heel is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- could not find heel bone (that is, a bone with no children connected) attached to bone '%s'" % (strip_org(bone), strip_org(leg_bones[1])))
- # Get the toe
- toe = None
- for b in self.obj.data.bones[foot].children:
- if b.use_connect is True:
- toe = b.name
-
- if toe is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type -- toe is None" % (strip_org(bone)))
-
- self.org_bones = leg_bones + [foot, toe, heel]
-
- # Get rig parameters
- if params.separate_hose_layers:
- layers = list(params.hose_layers)
- else:
- layers = None
- use_complex_rig = params.use_complex_leg
- knee_base_name = params.knee_base_name
- primary_rotation_axis = params.primary_rotation_axis
-
- # Based on common limb
- self.rubber_hose_limb = limb_common.RubberHoseLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], use_complex_rig, knee_base_name, primary_rotation_axis, layers)
-
- def generate(self):
- bone_list = self.rubber_hose_limb.generate()
-
- # Set up toe
- bpy.ops.object.mode_set(mode='EDIT')
- toe = copy_bone(self.obj, self.org_bones[3], make_deformer_name(strip_org(self.org_bones[3])))
- eb = self.obj.data.edit_bones
- eb[toe].use_connect = False
- eb[toe].parent = eb[self.org_bones[3]]
-
- return bone_list
diff --git a/rigify/rigs/biped/leg/fk.py b/rigify/rigs/biped/leg/fk.py
deleted file mode 100644
index bf055fa5..00000000
--- a/rigify/rigs/biped/leg/fk.py
+++ /dev/null
@@ -1,130 +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 bpy
-from mathutils import Vector
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import connected_children_names, has_connected_children
-from ....utils import strip_org
-from ....utils import get_layers
-from ....utils import create_widget
-
-
-class Rig:
- """ An FK leg rig, with hinge switch.
-
- """
- 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, and
- store names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
-
- """
- self.obj = obj
- self.params = params
-
- # Get the chain of 2 connected bones
- leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]
-
- if len(leg_bones) != 2:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- # Get the foot and heel
- foot = None
- heel = None
- for b in self.obj.data.bones[leg_bones[1]].children:
- if b.use_connect is True:
- if len(b.children) >= 1 and has_connected_children(b):
- foot = b.name
- else:
- heel = b.name
-
- if foot is None or heel is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- # Get the toe
- toe = None
- for b in self.obj.data.bones[foot].children:
- if b.use_connect is True:
- toe = b.name
-
- # Get the toe
- if toe is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- self.org_bones = leg_bones + [foot, toe, heel]
-
- # Get (optional) parent
- if self.obj.data.bones[bone].parent is None:
- self.org_parent = None
- else:
- self.org_parent = self.obj.data.bones[bone].parent.name
-
- # Get rig parameters
- if "layers" in params:
- layers = get_layers(params["layers"])
- else:
- layers = None
-
- primary_rotation_axis = params.primary_rotation_axis
-
- # Leg is based on common limb
- self.fk_limb = limb_common.FKLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], primary_rotation_axis, layers)
-
- 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.
-
- """
- ctrl_bones = self.fk_limb.generate()
- thigh = ctrl_bones[0]
- shin = ctrl_bones[1]
- foot = ctrl_bones[2]
- foot_mch = ctrl_bones[3]
-
- # Position foot control
- bpy.ops.object.mode_set(mode='EDIT')
- eb = self.obj.data.edit_bones
- foot_e = eb[foot]
- vec = Vector(eb[self.org_bones[3]].vector)
- vec.normalize()
- foot_e.tail = foot_e.head + (vec * foot_e.length)
- foot_e.roll = eb[self.org_bones[3]].roll
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Create foot widget
- ob = create_widget(self.obj, foot)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [thigh, shin, foot, foot_mch]
diff --git a/rigify/rigs/biped/leg/ik.py b/rigify/rigs/biped/leg/ik.py
deleted file mode 100644
index 82422e27..00000000
--- a/rigify/rigs/biped/leg/ik.py
+++ /dev/null
@@ -1,350 +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 bpy
-from mathutils import Vector
-
-from .. import limb_common
-
-from ....utils import MetarigError
-from ....utils import align_bone_x_axis
-from ....utils import copy_bone, flip_bone, put_bone
-from ....utils import connected_children_names, has_connected_children
-from ....utils import strip_org, make_mechanism_name, insert_before_lr
-from ....utils import create_widget, create_circle_widget
-
-
-class Rig:
- """ An IK leg rig, with an optional ik/fk switch.
-
- """
- def __init__(self, obj, bone, params, ikfk_switch=False):
- """ 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, and
- store names of bones that will be needed.
- Do NOT change any data in the scene. This is a gathering phase only.
- """
- self.obj = obj
- self.params = params
- self.switch = ikfk_switch
-
- # Get the chain of 2 connected bones
- leg_bones = [bone] + connected_children_names(self.obj, bone)[:2]
-
- if len(leg_bones) != 2:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- # Get the foot and heel
- foot = None
- heel = None
- rocker = None
- for b in self.obj.data.bones[leg_bones[1]].children:
- if b.use_connect is True:
- if len(b.children) >= 1 and has_connected_children(b):
- foot = b.name
- else:
- heel = b.name
- if len(b.children) > 0:
- rocker = b.children[0].name
-
- if foot is None or heel is None:
- print("blah")
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- # Get the toe
- toe = None
- for b in self.obj.data.bones[foot].children:
- if b.use_connect is True:
- toe = b.name
-
- # Get toe
- if toe is None:
- raise MetarigError("RIGIFY ERROR: Bone '%s': incorrect bone configuration for rig type" % (strip_org(bone)))
-
- self.org_bones = leg_bones + [foot, toe, heel, rocker]
-
- # Get rig parameters
- if params.separate_ik_layers:
- self.layers = list(params.ik_layers)
- else:
- self.layers = None
- bend_hint = params.bend_hint
- primary_rotation_axis = params.primary_rotation_axis
- pole_target_base_name = self.params.knee_base_name + "_target"
-
- # Leg is based on common limb
- self.ik_limb = limb_common.IKLimb(obj, self.org_bones[0], self.org_bones[1], self.org_bones[2], self.org_bones[2], pole_target_base_name, primary_rotation_axis, bend_hint, self.layers, ikfk_switch)
-
- 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.
- """
- # Generate base IK limb
- bone_list = self.ik_limb.generate()
- thigh = bone_list[0]
- shin = bone_list[1]
- foot = bone_list[2]
- foot_mch = bone_list[3]
- pole = bone_list[4]
- # vispole = bone_list[5]
- # visfoot = bone_list[6]
-
- # Build IK foot rig
- bpy.ops.object.mode_set(mode='EDIT')
- make_rocker = False
- if self.org_bones[5] is not None:
- make_rocker = True
-
- # Create the bones
- toe = copy_bone(self.obj, self.org_bones[3], strip_org(self.org_bones[3]))
- toe_parent = copy_bone(self.obj, self.org_bones[2], make_mechanism_name(strip_org(self.org_bones[3] + ".parent")))
- toe_parent_socket1 = copy_bone(self.obj, self.org_bones[2], make_mechanism_name(strip_org(self.org_bones[3] + ".socket1")))
- toe_parent_socket2 = copy_bone(self.obj, self.org_bones[2], make_mechanism_name(strip_org(self.org_bones[3] + ".socket2")))
-
- foot_roll = copy_bone(self.obj, self.org_bones[4], strip_org(insert_before_lr(self.org_bones[2], "_roll.ik")))
- roll1 = copy_bone(self.obj, self.org_bones[4], make_mechanism_name(strip_org(self.org_bones[2] + ".roll.01")))
- roll2 = copy_bone(self.obj, self.org_bones[4], make_mechanism_name(strip_org(self.org_bones[2] + ".roll.02")))
-
- if make_rocker:
- rocker1 = copy_bone(self.obj, self.org_bones[5], make_mechanism_name(strip_org(self.org_bones[2] + ".rocker.01")))
- rocker2 = copy_bone(self.obj, self.org_bones[5], make_mechanism_name(strip_org(self.org_bones[2] + ".rocker.02")))
-
- # Get edit bones
- eb = self.obj.data.edit_bones
-
- org_foot_e = eb[self.org_bones[2]]
- foot_e = eb[foot]
- foot_ik_target_e = eb[foot_mch]
- toe_e = eb[toe]
- toe_parent_e = eb[toe_parent]
- toe_parent_socket1_e = eb[toe_parent_socket1]
- toe_parent_socket2_e = eb[toe_parent_socket2]
- foot_roll_e = eb[foot_roll]
- roll1_e = eb[roll1]
- roll2_e = eb[roll2]
- if make_rocker:
- rocker1_e = eb[rocker1]
- rocker2_e = eb[rocker2]
-
- # Parenting
- foot_ik_target_e.use_connect = False
- foot_ik_target_e.parent = roll2_e
-
- toe_e.parent = toe_parent_e
- toe_parent_e.use_connect = False
- toe_parent_e.parent = toe_parent_socket1_e
- toe_parent_socket1_e.use_connect = False
- toe_parent_socket1_e.parent = roll1_e
- toe_parent_socket2_e.use_connect = False
- toe_parent_socket2_e.parent = eb[self.org_bones[2]]
-
- foot_roll_e.use_connect = False
- foot_roll_e.parent = foot_e
-
- roll1_e.use_connect = False
- roll1_e.parent = foot_e
-
- roll2_e.use_connect = False
- roll2_e.parent = roll1_e
-
- if make_rocker:
- rocker1_e.use_connect = False
- rocker2_e.use_connect = False
-
- roll1_e.parent = rocker2_e
- rocker2_e.parent = rocker1_e
- rocker1_e.parent = foot_e
-
- # Positioning
- vec = Vector(toe_e.vector)
- vec.normalize()
- foot_e.tail = foot_e.head + (vec * foot_e.length)
- foot_e.roll = toe_e.roll
-
- flip_bone(self.obj, toe_parent_socket1)
- flip_bone(self.obj, toe_parent_socket2)
- toe_parent_socket1_e.head = Vector(org_foot_e.tail)
- toe_parent_socket2_e.head = Vector(org_foot_e.tail)
- toe_parent_socket1_e.tail = Vector(org_foot_e.tail) + (Vector((0, 0, 1)) * foot_e.length / 2)
- toe_parent_socket2_e.tail = Vector(org_foot_e.tail) + (Vector((0, 0, 1)) * foot_e.length / 3)
- toe_parent_socket2_e.roll = toe_parent_socket1_e.roll
-
- tail = Vector(roll1_e.tail)
- roll1_e.tail = Vector(org_foot_e.tail)
- roll1_e.tail = Vector(org_foot_e.tail)
- roll1_e.head = tail
- roll2_e.head = Vector(org_foot_e.tail)
- foot_roll_e.head = Vector(org_foot_e.tail)
- put_bone(self.obj, foot_roll, roll1_e.head)
- foot_roll_e.length /= 2
-
- roll_axis = roll1_e.vector.cross(org_foot_e.vector)
- align_bone_x_axis(self.obj, roll1, roll_axis)
- align_bone_x_axis(self.obj, roll2, roll_axis)
- foot_roll_e.roll = roll2_e.roll
-
- if make_rocker:
- d = toe_e.y_axis.dot(rocker1_e.x_axis)
- if d >= 0.0:
- flip_bone(self.obj, rocker2)
- else:
- flip_bone(self.obj, rocker1)
-
- # Object mode, get pose bones
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- foot_p = pb[foot]
- foot_roll_p = pb[foot_roll]
- roll1_p = pb[roll1]
- roll2_p = pb[roll2]
- if make_rocker:
- rocker1_p = pb[rocker1]
- rocker2_p = pb[rocker2]
- toe_p = pb[toe]
- # toe_parent_p = pb[toe_parent]
- toe_parent_socket1_p = pb[toe_parent_socket1]
-
- # Foot roll control only rotates on x-axis, or x and y if rocker.
- foot_roll_p.rotation_mode = 'XYZ'
- if make_rocker:
- foot_roll_p.lock_rotation = False, False, True
- else:
- foot_roll_p.lock_rotation = False, True, True
- foot_roll_p.lock_location = True, True, True
- foot_roll_p.lock_scale = True, True, True
-
- # roll and rocker bones set to euler rotation
- roll1_p.rotation_mode = 'XYZ'
- roll2_p.rotation_mode = 'XYZ'
- if make_rocker:
- rocker1_p.rotation_mode = 'XYZ'
- rocker2_p.rotation_mode = 'XYZ'
-
- # toe_parent constraint
- con = toe_parent_socket1_p.constraints.new('COPY_LOCATION')
- con.name = "copy_location"
- con.target = self.obj
- con.subtarget = toe_parent_socket2
-
- con = toe_parent_socket1_p.constraints.new('COPY_SCALE')
- con.name = "copy_scale"
- con.target = self.obj
- con.subtarget = toe_parent_socket2
-
- con = toe_parent_socket1_p.constraints.new('COPY_TRANSFORMS') # drive with IK switch
- con.name = "fk"
- con.target = self.obj
- con.subtarget = toe_parent_socket2
-
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = foot_p.path_from_id() + '["ikfk_switch"]'
- mod = fcurve.modifiers[0]
- mod.poly_order = 1
- mod.coefficients[0] = 1.0
- mod.coefficients[1] = -1.0
-
- # Foot roll drivers
- fcurve = roll1_p.driver_add("rotation_euler", 0)
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- driver.expression = "min(0,var)"
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = foot_roll_p.path_from_id() + '.rotation_euler[0]'
-
- fcurve = roll2_p.driver_add("rotation_euler", 0)
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- driver.expression = "max(0,var)"
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = foot_roll_p.path_from_id() + '.rotation_euler[0]'
-
- if make_rocker:
- fcurve = rocker1_p.driver_add("rotation_euler", 0)
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- driver.expression = "max(0,-var)"
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = foot_roll_p.path_from_id() + '.rotation_euler[1]'
-
- fcurve = rocker2_p.driver_add("rotation_euler", 0)
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- driver.expression = "max(0,var)"
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = foot_roll_p.path_from_id() + '.rotation_euler[1]'
-
- # Constrain toe bone to toe control
- con = pb[self.org_bones[3]].constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = toe
-
- # Set layers if specified
- if self.layers:
- foot_roll_p.bone.layers = self.layers
- toe_p.bone.layers = [(i[0] or i[1]) for i in zip(toe_p.bone.layers, self.layers)] # Both FK and IK layers
-
- # Create widgets
- create_circle_widget(self.obj, toe, radius=0.7, head_tail=0.5)
-
- ob = create_widget(self.obj, foot_roll)
- if ob is not None:
- verts = [(0.3999999761581421, 0.766044557094574, 0.6427875757217407), (0.17668449878692627, 3.823702598992895e-08, 3.2084670920085046e-08), (-0.17668461799621582, 9.874240447516058e-08, 8.285470443070153e-08), (-0.39999961853027344, 0.7660449147224426, 0.6427879333496094), (0.3562471270561218, 0.6159579753875732, 0.5168500542640686), (-0.35624682903289795, 0.6159582138061523, 0.5168502926826477), (0.20492683351039886, 0.09688037633895874, 0.0812922865152359), (-0.20492687821388245, 0.0968804731965065, 0.08129236847162247)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (1, 6), (4, 6), (2, 7), (5, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- ob = create_widget(self.obj, foot)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [thigh, shin, foot, pole, foot_roll, foot_mch]
diff --git a/rigify/rigs/biped/limb_common.py b/rigify/rigs/biped/limb_common.py
deleted file mode 100644
index eadd6374..00000000
--- a/rigify/rigs/biped/limb_common.py
+++ /dev/null
@@ -1,1287 +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 ========================
-
-from math import pi
-
-import bpy
-from rna_prop_ui import rna_idprop_ui_prop_get
-from mathutils import Vector
-
-from ...utils import angle_on_plane, align_bone_roll, align_bone_z_axis
-from ...utils import new_bone, copy_bone, put_bone, make_nonscaling_child
-from ...utils import strip_org, make_mechanism_name, make_deformer_name, insert_before_lr
-from ...utils import create_widget, create_limb_widget, create_line_widget, create_sphere_widget
-
-
-class FKLimb:
- def __init__(self, obj, bone1, bone2, bone3, primary_rotation_axis, layers):
- self.obj = obj
-
- self.org_bones = [bone1, bone2, bone3]
-
- # Get (optional) parent
- if self.obj.data.bones[bone1].parent is None:
- self.org_parent = None
- else:
- self.org_parent = self.obj.data.bones[bone1].parent.name
-
- # Get the rig parameters
- self.layers = layers
- self.primary_rotation_axis = primary_rotation_axis
-
- def generate(self):
- bpy.ops.object.mode_set(mode='EDIT')
-
- # Create non-scaling parent bone
- if self.org_parent is not None:
- loc = Vector(self.obj.data.edit_bones[self.org_bones[0]].head)
- parent = make_nonscaling_child(self.obj, self.org_parent, loc, "_fk")
- else:
- parent = None
-
- # Create the control bones
- ulimb = copy_bone(self.obj, self.org_bones[0], strip_org(insert_before_lr(self.org_bones[0], ".fk")))
- flimb = copy_bone(self.obj, self.org_bones[1], strip_org(insert_before_lr(self.org_bones[1], ".fk")))
- elimb = copy_bone(self.obj, self.org_bones[2], strip_org(insert_before_lr(self.org_bones[2], ".fk")))
-
- # Create the end-limb mechanism bone
- elimb_mch = copy_bone(self.obj, self.org_bones[2], make_mechanism_name(strip_org(self.org_bones[2])))
-
- # Create the anti-stretch bones
- # These sit between a parent and its child, and counteract the
- # stretching of the parent so that the child is unaffected
- fantistr = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[0], "_antistr.fk"))))
- eantistr = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], "_antistr.fk"))))
-
- # Create the hinge bones
- if parent is not None:
- socket1 = copy_bone(self.obj, ulimb, make_mechanism_name(ulimb + ".socket1"))
- socket2 = copy_bone(self.obj, ulimb, make_mechanism_name(ulimb + ".socket2"))
-
- # Get edit bones
- eb = self.obj.data.edit_bones
-
- ulimb_e = eb[ulimb]
- flimb_e = eb[flimb]
- elimb_e = eb[elimb]
-
- fantistr_e = eb[fantistr]
- eantistr_e = eb[eantistr]
-
- elimb_mch_e = eb[elimb_mch]
-
- if parent is not None:
- socket1_e = eb[socket1]
- socket2_e = eb[socket2]
-
- # Parenting
- elimb_mch_e.use_connect = False
- elimb_mch_e.parent = elimb_e
-
- elimb_e.use_connect = False
- elimb_e.parent = eantistr_e
-
- eantistr_e.use_connect = False
- eantistr_e.parent = flimb_e
-
- flimb_e.use_connect = False
- flimb_e.parent = fantistr_e
-
- fantistr_e.use_connect = False
- fantistr_e.parent = ulimb_e
-
- if parent is not None:
- socket1_e.use_connect = False
- socket1_e.parent = eb[parent]
-
- socket2_e.use_connect = False
- socket2_e.parent = None
-
- ulimb_e.use_connect = False
- ulimb_e.parent = socket2_e
-
- # Positioning
- fantistr_e.length /= 8
- put_bone(self.obj, fantistr, Vector(ulimb_e.tail))
- eantistr_e.length /= 8
- put_bone(self.obj, eantistr, Vector(flimb_e.tail))
-
- if parent is not None:
- socket1_e.length /= 4
- socket2_e.length /= 3
-
- # Object mode, get pose bones
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- ulimb_p = pb[ulimb]
- flimb_p = pb[flimb]
- elimb_p = pb[elimb]
-
- fantistr_p = pb[fantistr]
- eantistr_p = pb[eantistr]
-
- if parent is not None:
- socket2_p = pb[socket2]
-
- # Lock axes
- ulimb_p.lock_location = (True, True, True)
- flimb_p.lock_location = (True, True, True)
- elimb_p.lock_location = (True, True, True)
-
- # Set the elbow to only bend on the x-axis.
- flimb_p.rotation_mode = 'XYZ'
- if 'X' in self.primary_rotation_axis:
- flimb_p.lock_rotation = (False, True, True)
- elif 'Y' in self.primary_rotation_axis:
- flimb_p.lock_rotation = (True, False, True)
- else:
- flimb_p.lock_rotation = (True, True, False)
-
- # Set up custom properties
- if parent is not None:
- prop = rna_idprop_ui_prop_get(ulimb_p, "isolate", create=True)
- ulimb_p["isolate"] = 0.0
- prop["soft_min"] = prop["min"] = 0.0
- prop["soft_max"] = prop["max"] = 1.0
-
- prop = rna_idprop_ui_prop_get(ulimb_p, "stretch_length", create=True)
- ulimb_p["stretch_length"] = 1.0
- prop["min"] = 0.05
- prop["max"] = 20.0
- prop["soft_min"] = 0.25
- prop["soft_max"] = 4.0
-
- # Stretch drivers
- def add_stretch_drivers(pose_bone):
- driver = pose_bone.driver_add("scale", 1).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "stretch_length"
-
- driver = pose_bone.driver_add("scale", 0).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "1/sqrt(stretch_length)"
-
- driver = pose_bone.driver_add("scale", 2).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "1/sqrt(stretch_length)"
-
- def add_antistretch_drivers(pose_bone):
- driver = pose_bone.driver_add("scale", 1).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "1/stretch_length"
-
- driver = pose_bone.driver_add("scale", 0).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "sqrt(stretch_length)"
-
- driver = pose_bone.driver_add("scale", 2).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "sqrt(stretch_length)"
-
- add_stretch_drivers(ulimb_p)
- add_stretch_drivers(flimb_p)
- add_antistretch_drivers(fantistr_p)
- add_antistretch_drivers(eantistr_p)
-
- # Hinge constraints / drivers
- if parent is not None:
- con = socket2_p.constraints.new('COPY_LOCATION')
- con.name = "copy_location"
- con.target = self.obj
- con.subtarget = socket1
-
- con = socket2_p.constraints.new('COPY_TRANSFORMS')
- con.name = "isolate_off"
- con.target = self.obj
- con.subtarget = socket1
-
- # Driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = ulimb_p.path_from_id() + '["isolate"]'
- mod = fcurve.modifiers[0]
- mod.poly_order = 1
- mod.coefficients[0] = 1.0
- mod.coefficients[1] = -1.0
-
- # Constrain org bones to controls
- con = pb[self.org_bones[0]].constraints.new('COPY_TRANSFORMS')
- con.name = "fk"
- con.target = self.obj
- con.subtarget = ulimb
-
- con = pb[self.org_bones[1]].constraints.new('COPY_TRANSFORMS')
- con.name = "fk"
- con.target = self.obj
- con.subtarget = flimb
-
- con = pb[self.org_bones[2]].constraints.new('COPY_TRANSFORMS')
- con.name = "fk"
- con.target = self.obj
- con.subtarget = elimb_mch
-
- # Set layers if specified
- if self.layers:
- ulimb_p.bone.layers = self.layers
- flimb_p.bone.layers = self.layers
- elimb_p.bone.layers = self.layers
-
- # Create control widgets
- create_limb_widget(self.obj, ulimb)
- create_limb_widget(self.obj, flimb)
-
- ob = create_widget(self.obj, elimb)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [ulimb, flimb, elimb, elimb_mch]
-
-
-class IKLimb:
- """ An IK limb rig, with an optional ik/fk switch.
-
- """
- def __init__(self, obj, bone1, bone2, bone3, pole_parent, pole_target_base_name, primary_rotation_axis, bend_hint, layers, ikfk_switch=False):
- self.obj = obj
- self.switch = ikfk_switch
-
- # Get the chain of 3 connected bones
- self.org_bones = [bone1, bone2, bone3]
-
- # Get (optional) parent
- if self.obj.data.bones[bone1].parent is None:
- self.org_parent = None
- else:
- self.org_parent = self.obj.data.bones[bone1].parent.name
-
- self.pole_parent = pole_parent
-
- # Get the rig parameters
- self.pole_target_base_name = pole_target_base_name
- self.layers = layers
- self.bend_hint = bend_hint
- self.primary_rotation_axis = primary_rotation_axis
-
- def generate(self):
- bpy.ops.object.mode_set(mode='EDIT')
-
- # Create non-scaling parent bone
- if self.org_parent is not None:
- loc = Vector(self.obj.data.edit_bones[self.org_bones[0]].head)
- parent = make_nonscaling_child(self.obj, self.org_parent, loc, "_ik")
- if self.pole_parent is None:
- self.pole_parent = parent
- else:
- parent = None
-
- # Create the bones
- ulimb = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[0], ".ik"))))
- flimb = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], ".ik"))))
- elimb = copy_bone(self.obj, self.org_bones[2], strip_org(insert_before_lr(self.org_bones[2], ".ik")))
- elimb_mch = copy_bone(self.obj, self.org_bones[2], make_mechanism_name(strip_org(self.org_bones[2])))
-
- ulimb_nostr = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[0], ".nostr.ik"))))
- flimb_nostr = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], ".nostr.ik"))))
-
- ulimb_str = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[0], ".stretch.ik"))))
- flimb_str = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], ".stretch.ik"))))
-
- pole_target_name = self.pole_target_base_name + "." + insert_before_lr(self.org_bones[0], ".ik").split(".", 1)[1]
- pole = copy_bone(self.obj, self.org_bones[0], pole_target_name)
- if self.pole_parent == self.org_bones[2]:
- self.pole_parent = elimb_mch
- if self.pole_parent is not None:
- pole_par = copy_bone(self.obj, self.pole_parent, make_mechanism_name(insert_before_lr(pole_target_name, "_parent")))
-
- viselimb = copy_bone(self.obj, self.org_bones[2], "VIS-" + strip_org(insert_before_lr(self.org_bones[2], ".ik")))
- vispole = copy_bone(self.obj, self.org_bones[1], "VIS-" + strip_org(insert_before_lr(self.org_bones[0], "_pole.ik")))
-
- # Get edit bones
- eb = self.obj.data.edit_bones
-
- if parent is not None:
- parent_e = eb[parent]
- ulimb_e = eb[ulimb]
- flimb_e = eb[flimb]
- elimb_e = eb[elimb]
- elimb_mch_e = eb[elimb_mch]
- ulimb_nostr_e = eb[ulimb_nostr]
- flimb_nostr_e = eb[flimb_nostr]
- ulimb_str_e = eb[ulimb_str]
- flimb_str_e = eb[flimb_str]
- pole_e = eb[pole]
- if self.pole_parent is not None:
- pole_par_e = eb[pole_par]
- viselimb_e = eb[viselimb]
- vispole_e = eb[vispole]
-
- # Parenting
- ulimb_e.use_connect = False
- ulimb_nostr_e.use_connect = False
- if parent is not None:
- ulimb_e.parent = parent_e
- ulimb_nostr_e.parent = parent_e
-
- flimb_e.parent = ulimb_e
- flimb_nostr_e.parent = ulimb_nostr_e
-
- elimb_e.use_connect = False
- elimb_e.parent = None
-
- elimb_mch_e.use_connect = False
- elimb_mch_e.parent = elimb_e
-
- ulimb_str_e.use_connect = False
- ulimb_str_e.parent = ulimb_e.parent
-
- flimb_str_e.use_connect = False
- flimb_str_e.parent = ulimb_e.parent
-
- pole_e.use_connect = False
- if self.pole_parent is not None:
- pole_par_e.parent = None
- pole_e.parent = pole_par_e
-
- viselimb_e.use_connect = False
- viselimb_e.parent = None
-
- vispole_e.use_connect = False
- vispole_e.parent = None
-
- # Misc
- elimb_e.use_local_location = False
-
- viselimb_e.hide_select = True
- vispole_e.hide_select = True
-
- # Positioning
- v1 = flimb_e.tail - ulimb_e.head
- if 'X' in self.primary_rotation_axis or 'Y' in self.primary_rotation_axis:
- v2 = v1.cross(flimb_e.x_axis)
- if (v2 * flimb_e.z_axis) > 0.0:
- v2 *= -1.0
- else:
- v2 = v1.cross(flimb_e.z_axis)
- if (v2 * flimb_e.x_axis) < 0.0:
- v2 *= -1.0
- v2.normalize()
- v2 *= v1.length
-
- if '-' in self.primary_rotation_axis:
- v2 *= -1
-
- pole_e.head = flimb_e.head + v2
- pole_e.tail = pole_e.head + (Vector((0, 1, 0)) * (v1.length / 8))
- pole_e.roll = 0.0
- if parent is not None:
- pole_par_e.length *= 0.75
-
- viselimb_e.tail = viselimb_e.head + Vector((0, 0, v1.length / 32))
- vispole_e.tail = vispole_e.head + Vector((0, 0, v1.length / 32))
-
- # Determine the pole offset value
- plane = (flimb_e.tail - ulimb_e.head).normalized()
- vec1 = ulimb_e.x_axis.normalized()
- vec2 = (pole_e.head - ulimb_e.head).normalized()
- pole_offset = angle_on_plane(plane, vec1, vec2)
-
- # Object mode, get pose bones
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- ulimb_p = pb[ulimb]
- flimb_p = pb[flimb]
- elimb_p = pb[elimb]
- ulimb_nostr_p = pb[ulimb_nostr]
- flimb_nostr_p = pb[flimb_nostr]
- ulimb_str_p = pb[ulimb_str]
- flimb_str_p = pb[flimb_str]
- pole_p = pb[pole]
- if self.pole_parent is not None:
- pole_par_p = pb[pole_par]
- viselimb_p = pb[viselimb]
- vispole_p = pb[vispole]
-
- # Set the elbow to only bend on the primary axis
- if 'X' in self.primary_rotation_axis:
- flimb_p.lock_ik_y = True
- flimb_p.lock_ik_z = True
- flimb_nostr_p.lock_ik_y = True
- flimb_nostr_p.lock_ik_z = True
- elif 'Y' in self.primary_rotation_axis:
- flimb_p.lock_ik_x = True
- flimb_p.lock_ik_z = True
- flimb_nostr_p.lock_ik_x = True
- flimb_nostr_p.lock_ik_z = True
- else:
- flimb_p.lock_ik_x = True
- flimb_p.lock_ik_y = True
- flimb_nostr_p.lock_ik_x = True
- flimb_nostr_p.lock_ik_y = True
-
- # Limb stretches
- ulimb_nostr_p.ik_stretch = 0.0
- flimb_nostr_p.ik_stretch = 0.0
-
- # This next bit is weird. The values calculated cause
- # ulimb and flimb to preserve their relative lengths
- # while stretching.
- l1 = ulimb_p.length
- l2 = flimb_p.length
- if l1 < l2:
- ulimb_p.ik_stretch = (l1 ** (1 / 3)) / (l2 ** (1 / 3))
- flimb_p.ik_stretch = 1.0
- else:
- ulimb_p.ik_stretch = 1.0
- flimb_p.ik_stretch = (l2 ** (1 / 3)) / (l1 ** (1 / 3))
-
- # Pole target only translates
- pole_p.lock_location = False, False, False
- pole_p.lock_rotation = True, True, True
- pole_p.lock_rotation_w = True
- pole_p.lock_scale = True, True, True
-
- # Set up custom properties
- if self.switch is True:
- prop = rna_idprop_ui_prop_get(elimb_p, "ikfk_switch", create=True)
- elimb_p["ikfk_switch"] = 0.0
- prop["soft_min"] = prop["min"] = 0.0
- prop["soft_max"] = prop["max"] = 1.0
-
- if self.pole_parent is not None:
- prop = rna_idprop_ui_prop_get(pole_p, "follow", create=True)
- pole_p["follow"] = 1.0
- prop["soft_min"] = prop["min"] = 0.0
- prop["soft_max"] = prop["max"] = 1.0
-
- prop = rna_idprop_ui_prop_get(elimb_p, "stretch_length", create=True)
- elimb_p["stretch_length"] = 1.0
- prop["min"] = 0.05
- prop["max"] = 20.0
- prop["soft_min"] = 0.25
- prop["soft_max"] = 4.0
-
- prop = rna_idprop_ui_prop_get(elimb_p, "auto_stretch", create=True)
- elimb_p["auto_stretch"] = 1.0
- prop["soft_min"] = prop["min"] = 0.0
- prop["soft_max"] = prop["max"] = 1.0
-
- # Stretch parameter drivers
- def add_stretch_drivers(pose_bone):
- driver = pose_bone.driver_add("scale", 1).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "stretch_length"
-
- driver = pose_bone.driver_add("scale", 0).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "stretch_length"
-
- driver = pose_bone.driver_add("scale", 2).driver
- var = driver.variables.new()
- var.name = "stretch_length"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["stretch_length"]'
- driver.type = 'SCRIPTED'
- driver.expression = "stretch_length"
- add_stretch_drivers(ulimb_nostr_p)
-
- # Bend direction hint
- def add_bend_hint(pose_bone, axis):
- con = pose_bone.constraints.new('LIMIT_ROTATION')
- con.name = "bend_hint"
- con.owner_space = 'LOCAL'
- if axis == 'X':
- con.use_limit_x = True
- con.min_x = pi / 10
- con.max_x = pi / 10
- elif axis == '-X':
- con.use_limit_x = True
- con.min_x = -pi / 10
- con.max_x = -pi / 10
- elif axis == 'Y':
- con.use_limit_y = True
- con.min_y = pi / 10
- con.max_y = pi / 10
- elif axis == '-Y':
- con.use_limit_y = True
- con.min_y = -pi / 10
- con.max_y = -pi / 10
- elif axis == 'Z':
- con.use_limit_z = True
- con.min_z = pi / 10
- con.max_z = pi / 10
- elif axis == '-Z':
- con.use_limit_z = True
- con.min_z = -pi / 10
- con.max_z = -pi / 10
- if self.bend_hint:
- add_bend_hint(flimb_p, self.primary_rotation_axis)
- add_bend_hint(flimb_nostr_p, self.primary_rotation_axis)
-
- # Constrain normal IK chain to no-stretch IK chain
- con = ulimb_p.constraints.new('COPY_TRANSFORMS')
- con.name = "pre_stretch"
- con.target = self.obj
- con.subtarget = ulimb_nostr
-
- con = flimb_p.constraints.new('COPY_TRANSFORMS')
- con.name = "pre_stretch"
- con.target = self.obj
- con.subtarget = flimb_nostr
-
- # IK Constraints
- con = flimb_nostr_p.constraints.new('IK')
- con.name = "ik"
- con.target = self.obj
- con.subtarget = elimb_mch
- con.pole_target = self.obj
- con.pole_subtarget = pole
- con.pole_angle = pole_offset
- con.chain_count = 2
-
- con = flimb_p.constraints.new('IK')
- con.name = "ik"
- con.target = self.obj
- con.subtarget = elimb_mch
- con.chain_count = 2
-
- # Driver to enable/disable auto stretching IK chain
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["auto_stretch"]'
-
- # Stretch bone constraints
- con = ulimb_str_p.constraints.new('COPY_TRANSFORMS')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = ulimb
- con = ulimb_str_p.constraints.new('MAINTAIN_VOLUME')
- con.name = "stretch"
- con.owner_space = 'LOCAL'
-
- con = flimb_str_p.constraints.new('COPY_TRANSFORMS')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = flimb
- con = flimb_str_p.constraints.new('MAINTAIN_VOLUME')
- con.name = "stretch"
- con.owner_space = 'LOCAL'
-
- # Pole target parent
- if self.pole_parent is not None:
- con = pole_par_p.constraints.new('COPY_TRANSFORMS')
- con.name = "parent"
- con.target = self.obj
- con.subtarget = self.pole_parent
-
- driver = con.driver_add("influence").driver
- var = driver.variables.new()
- var.name = "follow"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = pole_p.path_from_id() + '["follow"]'
- driver.type = 'SUM'
-
- # Constrain org bones
- con = pb[self.org_bones[0]].constraints.new('COPY_TRANSFORMS')
- con.name = "ik"
- con.target = self.obj
- con.subtarget = ulimb_str
- if self.switch is True:
- # IK/FK switch driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["ikfk_switch"]'
-
- con = pb[self.org_bones[1]].constraints.new('COPY_TRANSFORMS')
- con.name = "ik"
- con.target = self.obj
- con.subtarget = flimb_str
- if self.switch is True:
- # IK/FK switch driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["ikfk_switch"]'
-
- con = pb[self.org_bones[2]].constraints.new('COPY_TRANSFORMS')
- con.name = "ik"
- con.target = self.obj
- con.subtarget = elimb_mch
- if self.switch is True:
- # IK/FK switch driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = elimb_p.path_from_id() + '["ikfk_switch"]'
-
- # VIS limb-end constraints
- con = viselimb_p.constraints.new('COPY_LOCATION')
- con.name = "copy_loc"
- con.target = self.obj
- con.subtarget = self.org_bones[2]
-
- con = viselimb_p.constraints.new('STRETCH_TO')
- con.name = "stretch_to"
- con.target = self.obj
- con.subtarget = elimb
- con.volume = 'NO_VOLUME'
- con.rest_length = viselimb_p.length
-
- # VIS pole constraints
- con = vispole_p.constraints.new('COPY_LOCATION')
- con.name = "copy_loc"
- con.target = self.obj
- con.subtarget = self.org_bones[1]
-
- con = vispole_p.constraints.new('STRETCH_TO')
- con.name = "stretch_to"
- con.target = self.obj
- con.subtarget = pole
- con.volume = 'NO_VOLUME'
- con.rest_length = vispole_p.length
-
- # Set layers if specified
- if self.layers:
- elimb_p.bone.layers = self.layers
- pole_p.bone.layers = self.layers
- viselimb_p.bone.layers = self.layers
- vispole_p.bone.layers = self.layers
-
- # Create widgets
- create_line_widget(self.obj, vispole)
- create_line_widget(self.obj, viselimb)
- create_sphere_widget(self.obj, pole)
-
- ob = create_widget(self.obj, elimb)
- if ob is not None:
- verts = [(0.7, 1.5, 0.0), (0.7, -0.25, 0.0), (-0.7, -0.25, 0.0), (-0.7, 1.5, 0.0), (0.7, 0.723, 0.0), (-0.7, 0.723, 0.0), (0.7, 0.0, 0.0), (-0.7, 0.0, 0.0)]
- edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
- mesh = ob.data
- mesh.from_pydata(verts, edges, [])
- mesh.update()
-
- mod = ob.modifiers.new("subsurf", 'SUBSURF')
- mod.levels = 2
-
- return [ulimb, flimb, elimb, elimb_mch, pole, vispole, viselimb]
-
-
-class RubberHoseLimb:
- def __init__(self, obj, bone1, bone2, bone3, use_complex_limb, junc_base_name, primary_rotation_axis, layers):
- self.obj = obj
-
- # Get the chain of 3 connected bones
- self.org_bones = [bone1, bone2, bone3]
-
- # Get (optional) parent
- if self.obj.data.bones[bone1].parent is None:
- self.org_parent = None
- else:
- self.org_parent = self.obj.data.bones[bone1].parent.name
-
- # Get rig parameters
- self.layers = layers
- self.primary_rotation_axis = primary_rotation_axis
- self.use_complex_limb = use_complex_limb
- self.junc_base_name = junc_base_name
-
- def generate(self):
- bpy.ops.object.mode_set(mode='EDIT')
-
- # Create non-scaling parent bone
- if self.org_parent is not None:
- loc = Vector(self.obj.data.edit_bones[self.org_bones[0]].head)
- parent = make_nonscaling_child(self.obj, self.org_parent, loc, "_rh")
- else:
- parent = None
-
- if not self.use_complex_limb:
- # Simple rig
-
- # Create bones
- ulimb = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(self.org_bones[0])))
- flimb = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(self.org_bones[1])))
- elimb = copy_bone(self.obj, self.org_bones[2], make_deformer_name(strip_org(self.org_bones[2])))
-
- # Get edit bones
- eb = self.obj.data.edit_bones
-
- ulimb_e = eb[ulimb]
- flimb_e = eb[flimb]
- elimb_e = eb[elimb]
-
- # Parenting
- elimb_e.parent = flimb_e
- elimb_e.use_connect = True
-
- flimb_e.parent = ulimb_e
- flimb_e.use_connect = True
-
- if parent is not None:
- elimb_e.use_connect = False
- ulimb_e.parent = eb[parent]
-
- # Object mode, get pose bones
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- ulimb_p = pb[ulimb]
- flimb_p = pb[flimb]
- elimb_p = pb[elimb]
-
- # Constrain def bones to org bones
- con = ulimb_p.constraints.new('COPY_TRANSFORMS')
- con.name = "def"
- con.target = self.obj
- con.subtarget = self.org_bones[0]
-
- con = flimb_p.constraints.new('COPY_TRANSFORMS')
- con.name = "def"
- con.target = self.obj
- con.subtarget = self.org_bones[1]
-
- con = elimb_p.constraints.new('COPY_TRANSFORMS')
- con.name = "def"
- con.target = self.obj
- con.subtarget = self.org_bones[2]
-
- return []
- else:
- # Complex rig
-
- # Get the .R or .L off the end of the upper limb name if it exists
- lr = self.org_bones[0].split(".", 1)
- if len(lr) == 1:
- lr = ""
- else:
- lr = lr[1]
-
- # Create bones
- # Deformation bones
- ulimb1 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(insert_before_lr(self.org_bones[0], ".01"))))
- ulimb2 = copy_bone(self.obj, self.org_bones[0], make_deformer_name(strip_org(insert_before_lr(self.org_bones[0], ".02"))))
- flimb1 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(insert_before_lr(self.org_bones[1], ".01"))))
- flimb2 = copy_bone(self.obj, self.org_bones[1], make_deformer_name(strip_org(insert_before_lr(self.org_bones[1], ".02"))))
- elimb = copy_bone(self.obj, self.org_bones[2], make_deformer_name(strip_org(self.org_bones[2])))
-
- # Bones for switchable smooth bbone transition at elbow/knee
- ulimb2_smoother = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[0], "_smth.02"))))
- flimb1_smoother = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], "_smth.01"))))
- flimb1_pos = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], ".01"))))
-
- # Elbow/knee junction bone
- junc = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(self.org_bones[1], ".junc"))))
-
- # Hose controls
- uhoseend = new_bone(self.obj, strip_org(insert_before_lr(self.org_bones[0], "_hose_end")))
- uhose = new_bone(self.obj, strip_org(insert_before_lr(self.org_bones[0], "_hose")))
- jhose = new_bone(self.obj, self.junc_base_name + "_hose." + lr)
- fhose = new_bone(self.obj, strip_org(insert_before_lr(self.org_bones[1], "_hose")))
- fhoseend = new_bone(self.obj, strip_org(insert_before_lr(self.org_bones[1], "_hose_end")))
-
- # Hose control parents
- uhoseend_par = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(uhoseend, "_p"))))
- uhose_par = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(uhose, "_p"))))
- jhose_par = copy_bone(self.obj, junc, make_mechanism_name(strip_org(insert_before_lr(jhose, "_p"))))
- fhose_par = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(fhose, "_p"))))
- fhoseend_par = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(fhoseend, "_p"))))
-
- # Get edit bones
- eb = self.obj.data.edit_bones
-
- if parent is not None:
- parent_e = eb[parent]
- else:
- parent_e = None
-
- ulimb1_e = eb[ulimb1]
- ulimb2_e = eb[ulimb2]
- flimb1_e = eb[flimb1]
- flimb2_e = eb[flimb2]
- elimb_e = eb[elimb]
-
- ulimb2_smoother_e = eb[ulimb2_smoother]
- flimb1_smoother_e = eb[flimb1_smoother]
- flimb1_pos_e = eb[flimb1_pos]
-
- junc_e = eb[junc]
-
- uhoseend_e = eb[uhoseend]
- uhose_e = eb[uhose]
- jhose_e = eb[jhose]
- fhose_e = eb[fhose]
- fhoseend_e = eb[fhoseend]
-
- uhoseend_par_e = eb[uhoseend_par]
- uhose_par_e = eb[uhose_par]
- jhose_par_e = eb[jhose_par]
- fhose_par_e = eb[fhose_par]
- fhoseend_par_e = eb[fhoseend_par]
-
- # Parenting
- if parent is not None:
- ulimb1_e.use_connect = False
- ulimb1_e.parent = parent_e
-
- ulimb2_e.use_connect = False
- ulimb2_e.parent = eb[self.org_bones[0]]
-
- ulimb2_smoother_e.use_connect = True
- ulimb2_smoother_e.parent = ulimb2_e
-
- flimb1_e.use_connect = True
- flimb1_e.parent = flimb1_smoother_e
-
- flimb1_smoother_e.use_connect = False
- flimb1_smoother_e.parent = flimb1_pos_e
-
- flimb1_pos_e.use_connect = False
- flimb1_pos_e.parent = eb[self.org_bones[1]]
-
- flimb2_e.use_connect = False
- flimb2_e.parent = eb[self.org_bones[1]]
-
- elimb_e.use_connect = False
- elimb_e.parent = eb[self.org_bones[2]]
-
- junc_e.use_connect = False
- junc_e.parent = eb[self.org_bones[0]]
-
- uhoseend_e.use_connect = False
- uhoseend_e.parent = uhoseend_par_e
-
- uhose_e.use_connect = False
- uhose_e.parent = uhose_par_e
-
- jhose_e.use_connect = False
- jhose_e.parent = jhose_par_e
-
- fhose_e.use_connect = False
- fhose_e.parent = fhose_par_e
-
- fhoseend_e.use_connect = False
- fhoseend_e.parent = fhoseend_par_e
-
- uhoseend_par_e.use_connect = False
- uhoseend_par_e.parent = parent_e
-
- uhose_par_e.use_connect = False
- uhose_par_e.parent = parent_e
-
- jhose_par_e.use_connect = False
- jhose_par_e.parent = parent_e
-
- fhose_par_e.use_connect = False
- fhose_par_e.parent = parent_e
-
- fhoseend_par_e.use_connect = False
- fhoseend_par_e.parent = parent_e
-
- # Positioning
- ulimb1_e.length *= 0.5
- ulimb2_e.head = Vector(ulimb1_e.tail)
- flimb1_e.length *= 0.5
- flimb2_e.head = Vector(flimb1_e.tail)
- align_bone_roll(self.obj, flimb2, elimb)
-
- ulimb2_smoother_e.tail = Vector(flimb1_e.tail)
- ulimb2_smoother_e.roll = flimb1_e.roll
-
- flimb1_smoother_e.head = Vector(ulimb1_e.tail)
- flimb1_pos_e.length *= 0.5
-
- junc_e.length *= 0.2
-
- uhoseend_par_e.length *= 0.25
- uhose_par_e.length *= 0.25
- jhose_par_e.length *= 0.15
- fhose_par_e.length *= 0.25
- fhoseend_par_e.length *= 0.25
- put_bone(self.obj, uhoseend_par, Vector(ulimb1_e.head))
- put_bone(self.obj, uhose_par, Vector(ulimb1_e.tail))
- put_bone(self.obj, jhose_par, Vector(ulimb2_e.tail))
- put_bone(self.obj, fhose_par, Vector(flimb1_e.tail))
- put_bone(self.obj, fhoseend_par, Vector(flimb2_e.tail))
-
- put_bone(self.obj, uhoseend, Vector(ulimb1_e.head))
- put_bone(self.obj, uhose, Vector(ulimb1_e.tail))
- put_bone(self.obj, jhose, Vector(ulimb2_e.tail))
- put_bone(self.obj, fhose, Vector(flimb1_e.tail))
- put_bone(self.obj, fhoseend, Vector(flimb2_e.tail))
-
- if 'X' in self.primary_rotation_axis:
- upoint = Vector(ulimb1_e.z_axis)
- fpoint = Vector(flimb1_e.z_axis)
- elif 'Z' in self.primary_rotation_axis:
- upoint = Vector(ulimb1_e.x_axis)
- fpoint = Vector(flimb1_e.x_axis)
- else: # Y
- upoint = Vector(ulimb1_e.z_axis)
- fpoint = Vector(flimb1_e.z_axis)
-
- if '-' not in self.primary_rotation_axis:
- upoint *= -1
- fpoint *= -1
-
- if 'Y' in self.primary_rotation_axis:
- uside = Vector(ulimb1_e.x_axis)
- fside = Vector(flimb1_e.x_axis)
- else:
- uside = Vector(ulimb1_e.y_axis) * -1
- fside = Vector(flimb1_e.y_axis) * -1
-
- uhoseend_e.tail = uhoseend_e.head + upoint
- uhose_e.tail = uhose_e.head + upoint
- jhose_e.tail = fhose_e.head + upoint + fpoint
- fhose_e.tail = fhose_e.head + fpoint
- fhoseend_e.tail = fhoseend_e.head + fpoint
-
- align_bone_z_axis(self.obj, uhoseend, uside)
- align_bone_z_axis(self.obj, uhose, uside)
- align_bone_z_axis(self.obj, jhose, uside + fside)
- align_bone_z_axis(self.obj, fhose, fside)
- align_bone_z_axis(self.obj, fhoseend, fside)
-
- l = 0.125 * (ulimb1_e.length + ulimb2_e.length + flimb1_e.length + flimb2_e.length)
- uhoseend_e.length = l
- uhose_e.length = l
- jhose_e.length = l
- fhose_e.length = l
- fhoseend_e.length = l
-
- # Object mode, get pose bones
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- ulimb1_p = pb[ulimb1]
- ulimb2_p = pb[ulimb2]
- flimb1_p = pb[flimb1]
- flimb2_p = pb[flimb2]
- elimb_p = pb[elimb]
-
- ulimb2_smoother_p = pb[ulimb2_smoother]
- flimb1_smoother_p = pb[flimb1_smoother]
- flimb1_pos_p = pb[flimb1_pos]
-
- junc_p = pb[junc]
-
- uhoseend_p = pb[uhoseend]
- uhose_p = pb[uhose]
- jhose_p = pb[jhose]
- fhose_p = pb[fhose]
- fhoseend_p = pb[fhoseend]
-
- #uhoseend_par_p = pb[uhoseend_par]
- uhose_par_p = pb[uhose_par]
- jhose_par_p = pb[jhose_par]
- fhose_par_p = pb[fhose_par]
- fhoseend_par_p = pb[fhoseend_par]
-
- # Lock axes
- uhose_p.lock_rotation = (True, True, True)
- uhose_p.lock_rotation_w = True
- uhose_p.lock_scale = (True, True, True)
-
- jhose_p.lock_rotation = (True, True, True)
- jhose_p.lock_rotation_w = True
- jhose_p.lock_scale = (True, True, True)
-
- fhose_p.lock_rotation = (True, True, True)
- fhose_p.lock_rotation_w = True
- fhose_p.lock_scale = (True, True, True)
-
- # B-bone settings
- ulimb2_p.bone.bbone_segments = 16
- ulimb2_p.bone.bbone_in = 0.0
- ulimb2_p.bone.bbone_out = 1.0
-
- ulimb2_smoother_p.bone.bbone_segments = 16
- ulimb2_smoother_p.bone.bbone_in = 1.0
- ulimb2_smoother_p.bone.bbone_out = 0.0
-
- flimb1_p.bone.bbone_segments = 16
- flimb1_p.bone.bbone_in = 1.0
- flimb1_p.bone.bbone_out = 0.0
-
- flimb1_smoother_p.bone.bbone_segments = 16
- flimb1_smoother_p.bone.bbone_in = 0.0
- flimb1_smoother_p.bone.bbone_out = 1.0
-
- # Custom properties
- prop = rna_idprop_ui_prop_get(jhose_p, "smooth_bend", create=True)
- jhose_p["smooth_bend"] = 0.0
- prop["soft_min"] = prop["min"] = 0.0
- prop["soft_max"] = prop["max"] = 1.0
-
- # Constraints
- con = ulimb1_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = uhoseend
- con = ulimb1_p.constraints.new('COPY_SCALE')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = self.org_bones[0]
- con = ulimb1_p.constraints.new('DAMPED_TRACK')
- con.name = "track"
- con.target = self.obj
- con.subtarget = uhose
- con = ulimb1_p.constraints.new('STRETCH_TO')
- con.name = "track"
- con.target = self.obj
- con.subtarget = uhose
- con.volume = 'NO_VOLUME'
-
- con = ulimb2_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = uhose
- con = ulimb2_p.constraints.new('DAMPED_TRACK')
- con.name = "track"
- con.target = self.obj
- con.subtarget = jhose
- con = ulimb2_p.constraints.new('STRETCH_TO')
- con.name = "track"
- con.target = self.obj
- con.subtarget = jhose
- con.volume = 'NO_VOLUME'
-
- con = ulimb2_smoother_p.constraints.new('COPY_TRANSFORMS')
- con.name = "smoother"
- con.target = self.obj
- con.subtarget = flimb1_pos
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SUM'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = jhose_p.path_from_id() + '["smooth_bend"]'
-
- con = flimb1_pos_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = jhose
- con = flimb1_pos_p.constraints.new('DAMPED_TRACK')
- con.name = "track"
- con.target = self.obj
- con.subtarget = fhose
- con = flimb1_pos_p.constraints.new('STRETCH_TO')
- con.name = "track"
- con.target = self.obj
- con.subtarget = fhose
- con.volume = 'NO_VOLUME'
-
- con = flimb1_p.constraints.new('COPY_TRANSFORMS')
- con.name = "position"
- con.target = self.obj
- con.subtarget = flimb1_pos
-
- con = flimb1_smoother_p.constraints.new('COPY_TRANSFORMS')
- con.name = "smoother"
- con.target = self.obj
- con.subtarget = ulimb2
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SUM'
- var.name = "var"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = jhose_p.path_from_id() + '["smooth_bend"]'
- con = flimb1_smoother_p.constraints.new('STRETCH_TO')
- con.name = "track"
- con.target = self.obj
- con.subtarget = jhose
- con.volume = 'NO_VOLUME'
-
- con = flimb2_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = fhose
- con = flimb2_p.constraints.new('COPY_ROTATION')
- con.name = "twist"
- con.target = self.obj
- con.subtarget = elimb
- con = flimb2_p.constraints.new('DAMPED_TRACK')
- con.name = "track"
- con.target = self.obj
- con.subtarget = fhoseend
- con = flimb2_p.constraints.new('STRETCH_TO')
- con.name = "track"
- con.target = self.obj
- con.subtarget = fhoseend
- con.volume = 'NO_VOLUME'
-
- con = junc_p.constraints.new('COPY_TRANSFORMS')
- con.name = "bend"
- con.target = self.obj
- con.subtarget = self.org_bones[1]
- con.influence = 0.5
-
- con = uhose_par_p.constraints.new('COPY_ROTATION')
- con.name = "follow"
- con.target = self.obj
- con.subtarget = self.org_bones[0]
- con.influence = 1.0
- con = uhose_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = self.org_bones[0]
- con.influence = 1.0
- con = uhose_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = jhose
- con.influence = 0.5
-
- con = jhose_par_p.constraints.new('COPY_ROTATION')
- con.name = "follow"
- con.target = self.obj
- con.subtarget = junc
- con.influence = 1.0
- con = jhose_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = junc
- con.influence = 1.0
-
- con = fhose_par_p.constraints.new('COPY_ROTATION')
- con.name = "follow"
- con.target = self.obj
- con.subtarget = self.org_bones[1]
- con.influence = 1.0
- con = fhose_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = jhose
- con.influence = 1.0
- con = fhose_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = self.org_bones[2]
- con.influence = 0.5
-
- con = fhoseend_par_p.constraints.new('COPY_ROTATION')
- con.name = "follow"
- con.target = self.obj
- con.subtarget = self.org_bones[1]
- con.influence = 1.0
- con = fhoseend_par_p.constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- con.subtarget = self.org_bones[2]
- con.influence = 1.0
-
- # Layers
- if self.layers:
- uhoseend_p.bone.layers = self.layers
- uhose_p.bone.layers = self.layers
- jhose_p.bone.layers = self.layers
- fhose_p.bone.layers = self.layers
- fhoseend_p.bone.layers = self.layers
- else:
- layers = list(pb[self.org_bones[0]].bone.layers)
- uhoseend_p.bone.layers = layers
- uhose_p.bone.layers = layers
- jhose_p.bone.layers = layers
- fhose_p.bone.layers = layers
- fhoseend_p.bone.layers = layers
-
- # Create widgets
- create_sphere_widget(self.obj, uhoseend)
- create_sphere_widget(self.obj, uhose)
- create_sphere_widget(self.obj, jhose)
- create_sphere_widget(self.obj, fhose)
- create_sphere_widget(self.obj, fhoseend)
-
- return [uhoseend, uhose, jhose, fhose, fhoseend]
diff --git a/rigify/rigs/biped/__init__.py b/rigify/rigs/experimental/__init__.py
index e69de29b..e69de29b 100644
--- a/rigify/rigs/biped/__init__.py
+++ b/rigify/rigs/experimental/__init__.py
diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
new file mode 100644
index 00000000..cff25f2a
--- /dev/null
+++ b/rigify/rigs/experimental/super_chain.py
@@ -0,0 +1,1414 @@
+import bpy
+from mathutils import Vector
+from math import pi
+from ...utils import copy_bone, flip_bone, put_bone, org, align_bone_y_axis, align_bone_x_axis, align_bone_z_axis
+from ...utils import strip_org, make_deformer_name, connected_children_names
+from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_chain_widget
+from ...utils import MetarigError, make_mechanism_name, create_cube_widget
+from rna_prop_ui import rna_idprop_ui_prop_get
+from ..limbs.limb_utils import get_bone_name
+
+script = """
+controls = [%s]
+torso = '%s'
+
+if is_selected( controls ):
+ layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
+ layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
+"""
+
+
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ """ A simplified version of the torso rig. Basically a connected-DEF chain of bones """
+
+ eb = obj.data.edit_bones
+
+ self.obj = obj
+ self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
+ self.params = params
+ self.spine_length = sum([eb[b].length for b in self.org_bones])
+ self.bbones = params.bbones
+
+ # Check if user provided the positions of the neck and pivot
+ # if params.neck_pos and params.pivot_pos:
+ # self.neck_pos = params.neck_pos
+ # self.pivot_pos = params.pivot_pos
+ # else:
+ # raise MetarigError(
+ # "RIGIFY ERROR: please specify neck and pivot bone positions"
+ # )
+ #
+ # # Check if neck is lower than pivot
+ # if params.neck_pos <= params.pivot_pos:
+ # raise MetarigError(
+ # "RIGIFY ERROR: Neck cannot be below or the same as pivot"
+ # )
+
+ # if params.control_num:
+ # self.control_num = params.control_num
+ # else:
+ # raise MetarigError(
+ # "RIGIFY ERROR: please specify number of controls"
+ # )
+ #
+ # if params.control_num > round(len(eb)/2):
+ # raise MetarigError(
+ # "RIGIFY ERROR: Number of controls must be <= number of bones/2"
+ # )
+
+ # TODO:
+ # Limit neck_pos prop to 1 --> num of bones - 1 (last is head)
+ # Limit pivot_pos prop to 2 --> num of bones (must leave place for lower torso)
+
+ # if params.tail_pos:
+ # self.tail_pos = params.tail_pos
+
+ # Assign values to tweak layers props if opted by user
+ if params.tweak_extra_layers:
+ self.tweak_layers = list(params.tweak_layers)
+ else:
+ self.tweak_layers = None
+
+ # Report error of user created less than the minimum of 4 bones for rig
+ # if len(self.org_bones) <= 4:
+ # raise MetarigError(
+ # "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
+ # )
+
+
+ # def build_bone_structure( self ):
+ # """ Divide meta-rig into lists of bones according to torso rig anatomy:
+ # Neck --> Upper torso --> Lower torso --> Tail (optional) """
+ #
+ # if self.pivot_pos and self.neck_pos:
+ #
+ # neck_index = self.neck_pos - 1
+ # pivot_index = self.pivot_pos - 1
+ #
+ # tail_index = 0
+ # if 'tail_pos' in dir(self):
+ # tail_index = self.tail_pos - 1
+ #
+ # neck_bones = self.org_bones[neck_index::]
+ # upper_torso_bones = self.org_bones[pivot_index:neck_index]
+ # lower_torso_bones = self.org_bones[tail_index:pivot_index]
+ #
+ # tail_bones = []
+ # if tail_index:
+ # tail_bones = self.org_bones[::tail_index+1]
+ #
+ # return {
+ # 'neck' : neck_bones,
+ # 'upper' : upper_torso_bones,
+ # 'lower' : lower_torso_bones,
+ # 'tail' : tail_bones
+ # }
+ #
+ # else:
+ # return 'ERROR'
+
+ def orient_bone( self, eb, axis, scale, reverse = False ):
+ v = Vector((0,0,0))
+
+ setattr(v,axis,scale)
+
+ if reverse:
+ tail_vec = v * self.obj.matrix_world
+ eb.head[:] = eb.tail
+ eb.tail[:] = eb.head + tail_vec
+ else:
+ tail_vec = v * self.obj.matrix_world
+ eb.tail[:] = eb.head + tail_vec
+
+ def create_pivot(self, bones=None, pivot=None):
+ """ Create the pivot control and mechanism bones """
+
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ if not pivot:
+ pivot = int(len(org_bones)/2)
+
+ pivot_name = org_bones[pivot]
+ if '.L' in pivot_name:
+ prefix = strip_org(org_bones[pivot]).split('.')[0] + '.L'
+ elif '.R' in pivot_name:
+ prefix = strip_org(org_bones[pivot]).split('.')[0] + '.R'
+ else:
+ prefix = strip_org(org_bones[pivot]).split('.')[0]
+
+ ctrl_name = get_bone_name(prefix, 'ctrl', 'pivot')
+ ctrl_name = copy_bone(self.obj, pivot_name, ctrl_name)
+ ctrl_eb = eb[ ctrl_name ]
+
+ self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 )
+
+ pivot_loc = eb[pivot_name].head + ((eb[pivot_name].tail - eb[pivot_name].head)/2)*(len(org_bones)%2)
+
+ put_bone( self.obj, ctrl_name, pivot_loc)
+
+ v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last
+ v.normalize()
+ v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v
+ v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain
+
+ if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03: #if v_point is too small it's not usable
+ v_point = eb[org_bones[0]].x_axis
+
+ if self.params.tweak_axis == 'auto':
+ align_bone_y_axis(self.obj, ctrl_name, v)
+ align_bone_z_axis(self.obj, ctrl_name, -v_point)
+ elif self.params.tweak_axis == 'x':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((1,0,0)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((0,0,1)))
+ elif self.params.tweak_axis == 'y':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((0,1,0)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0)))
+ elif self.params.tweak_axis == 'z':
+ align_bone_y_axis(self.obj, ctrl_name, Vector((0,0,1)))
+ align_bone_x_axis(self.obj, ctrl_name, Vector((1,0,0)))
+
+ return {
+ 'ctrl' : ctrl_name
+ }#Todo modify following
+
+
+ org_bones = self.org_bones
+ pivot_name = org_bones[pivot-1]
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create torso control bone
+ torso_name = 'torso'
+ ctrl_name = copy_bone(self.obj, pivot_name, torso_name)
+ ctrl_eb = eb[ctrl_name]
+
+ self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 )
+
+ # Create mch_pivot
+ mch_name = make_mechanism_name( 'pivot' )
+ mch_name = copy_bone(self.obj, ctrl_name, mch_name)
+ mch_eb = eb[mch_name]
+
+ mch_eb.length /= 4
+
+ # Positioning pivot in a more usable location for animators
+ if hasattr(self, 'tail_pos') and self.tail_pos > 0:
+ pivot_loc = eb[org_bones[pivot-1]].head
+ else:
+ pivot_loc = (eb[org_bones[0]].head + eb[org_bones[0]].tail) / 2
+
+ put_bone(self.obj, ctrl_name, pivot_loc)
+
+ return {
+ 'ctrl': ctrl_name,
+ 'mch': mch_name
+ }
+
+ def create_deform(self):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ def_bones = []
+ for o in org_bones:
+ def_name = make_deformer_name(strip_org(o))
+ def_name = copy_bone(self.obj, o, def_name)
+ def_bones.append(def_name)
+
+ bpy.ops.object.mode_set(mode='POSE')
+ # Create bbone segments
+ for bone in def_bones:
+ self.obj.data.bones[bone].bbone_segments = self.bbones
+
+ if not self.SINGLE_BONE:
+ self.obj.data.bones[def_bones[0]].bbone_in = 0.0
+ self.obj.data.bones[def_bones[-1]].bbone_out = 0.0
+ else:
+ self.obj.data.bones[def_bones[0]].bbone_in = 1.0
+ self.obj.data.bones[def_bones[-1]].bbone_out = 1.0
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ return def_bones
+
+ def create_neck( self, neck_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create neck control
+ neck = copy_bone( self.obj, org(neck_bones[0]), 'neck' )
+ neck_eb = eb[ neck ]
+
+ # Neck spans all neck bones (except head)
+ neck_eb.tail[:] = eb[ org(neck_bones[-1]) ].head
+
+ # Create head control
+ head = copy_bone( self.obj, org(neck_bones[-1]), 'head' )
+
+ # MCH bones
+ # Neck MCH stretch
+ mch_str = copy_bone( self.obj, neck, make_mechanism_name('STR-neck') )
+
+ # Neck MCH rotation
+ mch_neck = copy_bone(
+ self.obj, neck, make_mechanism_name('ROT-neck')
+ )
+
+ self.orient_bone( eb[mch_neck], 'y', self.spine_length / 10 )
+
+ # Head MCH rotation
+ mch_head = copy_bone(
+ self.obj, head, make_mechanism_name('ROT-head')
+ )
+
+ self.orient_bone( eb[mch_head], 'y', self.spine_length / 10 )
+
+ twk,mch = [],[]
+
+ # Intermediary bones
+ for b in neck_bones[1:-1]: # All except 1st neck and (last) head
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ eb[mch_name].length /= 4
+
+ mch += [ mch_name ]
+
+ # Tweak bones
+ for b in neck_bones[:-1]: # All except last bone
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org(b), twk_name )
+
+ eb[twk_name].length /= 2
+
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl_neck' : neck,
+ 'ctrl' : head,
+ 'mch_str' : mch_str,
+ 'mch_neck' : mch_neck,
+ 'mch_head' : mch_head,
+ 'mch' : mch,
+ 'tweak' : twk
+ }
+
+ def create_chest( self, chest_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # get total spine length
+
+ # Create chest control bone
+ chest = copy_bone( self.obj, org( chest_bones[0] ), 'chest' )
+ self.orient_bone( eb[chest], 'y', self.spine_length / 3 )
+
+ # create chest mch_wgt
+ mch_wgt = copy_bone(
+ self.obj, org( chest_bones[-1] ),
+ make_mechanism_name( 'WGT-chest' )
+ )
+
+ # Create mch and twk bones
+ twk,mch = [],[]
+
+ for b in chest_bones:
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ self.orient_bone( eb[mch_name], 'y', self.spine_length / 10 )
+
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org(b), twk_name )
+ eb[twk_name].length /= 2
+
+ mch += [ mch_name ]
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl' : chest,
+ 'mch' : mch,
+ 'tweak' : twk,
+ 'mch_wgt' : mch_wgt
+ }
+
+ def create_hips( self, hip_bones ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create hips control bone
+ hips = copy_bone( self.obj, org( hip_bones[-1] ), 'hips' )
+ self.orient_bone(
+ eb[hips],
+ 'y',
+ self.spine_length / 4,
+ reverse = True
+ )
+
+ # create hips mch_wgt
+ mch_wgt = copy_bone(
+ self.obj, org( hip_bones[0] ),
+ make_mechanism_name( 'WGT-hips' )
+ )
+
+ # Create mch and tweak bones
+ twk,mch = [],[]
+ for b in hip_bones:
+ mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
+ self.orient_bone(
+ eb[mch_name], 'y', self.spine_length / 10, reverse = True
+ )
+
+ twk_name = "tweak_" + b
+ twk_name = copy_bone( self.obj, org( b ), twk_name )
+
+ eb[twk_name].length /= 2
+
+ mch += [ mch_name ]
+ twk += [ twk_name ]
+
+ return {
+ 'ctrl' : hips,
+ 'mch' : mch,
+ 'tweak' : twk,
+ 'mch_wgt' : mch_wgt
+ }
+
+ def create_tail( self, tail_bones ):
+ pass
+
+ def create_chain(self):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ eb = self.obj.data.edit_bones
+
+ twk, mch, mch_ctrl, ctrl = [], [], [], []
+
+ suffix = ''
+ if '.L' in org_bones[0]:
+ suffix = '.L'
+ elif '.R' in org_bones[0]:
+ suffix = '.R'
+
+ mch_auto = ''
+ if not self.SINGLE_BONE:
+ mch_name = copy_bone( self.obj, org(org_bones[0]), 'MCH-AUTO-'+strip_org(org_bones[0]).split('.')[0] + suffix)
+ eb[mch_name].head = eb[org_bones[0]].head
+ eb[mch_name].tail = eb[org_bones[-1]].tail
+
+ mch_auto = mch_name
+
+ # Intermediary bones
+ for b in org_bones: # All
+
+ if self.SINGLE_BONE:
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+ put_bone(self.obj, mch_name, eb[b].head - (eb[mch_name].tail - eb[mch_name].head))
+ align_bone_z_axis(self.obj, mch_name, eb[b].z_axis)
+ if '.' in mch_name:
+ mch_rev_name = mch_name.split('.')[0] + '_reverse.' + mch_name.split('.')[1]
+ else:
+ mch_rev_name = mch_name + '_reverse'
+ mch_rev_name = copy_bone(self.obj, org(b), mch_rev_name)
+ eb[mch_rev_name].length /= 4
+ eb[mch_rev_name].tail = eb[mch_name].head
+ align_bone_z_axis(self.obj, mch_rev_name, eb[b].z_axis)
+ mch += [mch_name]
+ mch += [mch_rev_name]
+ break
+
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+
+ mch += [ mch_name ]
+
+ if b == org_bones[-1]: #Add extra
+ mch_name = copy_bone(self.obj, org(b), make_mechanism_name(strip_org(b)))
+ eb[mch_name].length /= 4
+ put_bone(self.obj, mch_name, eb[b].tail)
+ mch += [ mch_name ]
+
+ # Tweak & Ctrl bones
+ v = eb[org_bones[-1]].tail - eb[org_bones[0]].head # Create a vector from head of first ORG to tail of last
+ v.normalize()
+ v_proj = eb[org_bones[0]].y_axis.dot(v)*v # projection of first ORG to v
+ v_point = eb[org_bones[0]].y_axis - v_proj # a vector co-planar to first ORG and v directed out of the chain
+
+ if v_point.magnitude < eb[org_bones[0]].y_axis.magnitude*1e-03:
+ v_point = eb[org_bones[0]].x_axis
+
+ for b in org_bones: # All
+
+ suffix = ''
+ if '.L' in b:
+ suffix = '.L'
+ elif '.R' in b:
+ suffix = '.R'
+
+ if b == org_bones[0]:
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl')
+ name = copy_bone(self.obj, org(b), name)
+ align_bone_x_axis(self.obj, name, eb[org(b)].x_axis)
+ ctrl += [name]
+ else:
+ name = get_bone_name(b, 'ctrl', 'tweak')
+ name = copy_bone(self.obj, org(b), name)
+ twk += [name]
+
+ self.orient_bone(eb[name], 'y', eb[name].length / 2)
+
+ if self.params.tweak_axis == 'auto':
+ align_bone_y_axis(self.obj, name, v)
+ align_bone_z_axis(self.obj, name, -v_point) # invert?
+ elif self.params.tweak_axis == 'x':
+ align_bone_y_axis(self.obj, name, Vector((1,0,0)))
+ align_bone_x_axis(self.obj, name, Vector((0,0,1)))
+ elif self.params.tweak_axis == 'y':
+ align_bone_y_axis(self.obj, name, Vector((0,1,0)))
+ align_bone_x_axis(self.obj, name, Vector((1,0,0)))
+ elif self.params.tweak_axis == 'z':
+ align_bone_y_axis(self.obj, name, Vector((0,0,1)))
+ align_bone_x_axis(self.obj, name, Vector((1,0,0)))
+
+ if b == org_bones[-1]: # Add extra
+ ctrl_name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl')
+ ctrl_name = copy_bone(self.obj, org(b), ctrl_name)
+
+ self.orient_bone(eb[ctrl_name], 'y', eb[ctrl_name].length / 2)
+
+ #TODO check this if else
+ if self.params.conv_bone:
+ align_bone_y_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].y_axis)
+ align_bone_x_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].x_axis)
+ align_bone_z_axis(self.obj, ctrl_name, eb[org(self.params.conv_bone)].z_axis)
+
+ else:
+ if twk:
+ lastname = twk[-1]
+ else:
+ lastname = ctrl[-1]
+ align_bone_y_axis(self.obj, ctrl_name, eb[lastname].y_axis)
+ align_bone_x_axis(self.obj, ctrl_name, eb[lastname].x_axis)
+ put_bone(self.obj, ctrl_name, eb[b].tail)
+
+ ctrl += [ctrl_name]
+
+ conv_twk = ''
+ # Convergence tweak
+ if self.params.conv_bone:
+ conv_twk = get_bone_name(self.params.conv_bone, 'ctrl', 'tweak') #"tweak_" + self.params.conv_bone
+
+ if not(conv_twk in eb.keys()):
+ conv_twk = copy_bone( self.obj, org(self.params.conv_bone), conv_twk )
+
+ # Mch controls
+ suffix = ''
+ if '.L' in b:
+ suffix = '.L'
+ elif '.R' in b:
+ suffix = '.R'
+
+ for b in org_bones:
+ mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
+ mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name )
+
+ self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 )
+
+ if b == org_bones[0] or b == org_bones[-1]:
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b)
+ else:
+ name = get_bone_name(b, 'ctrl', 'tweak') #"tweak_" + strip_org(b)
+ # align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ # align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ if self.SINGLE_BONE:
+ align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis)
+
+ mch_ctrl += [mch_ctrl_name]
+
+ if b == org_bones[-1]: #Add extra
+ mch_ctrl_name = "MCH-CTRL-" + strip_org(b).split('.')[0] + suffix
+ mch_ctrl_name = copy_bone( self.obj, org(b), mch_ctrl_name )
+
+ self.orient_bone( eb[mch_ctrl_name], 'y', eb[mch_ctrl_name].length/6 )
+
+ name = get_bone_name(b.split('.')[0] + suffix, 'ctrl', 'ctrl') #"ctrl_" + strip_org(b)
+ #align_bone_y_axis(self.obj, mch_ctrl_name, -eb[name].z_axis)
+ align_bone_y_axis(self.obj, mch_ctrl_name, eb[name].y_axis)
+ align_bone_x_axis(self.obj, mch_ctrl_name, eb[name].x_axis)
+
+ put_bone(self.obj, mch_ctrl_name, eb[b].tail)
+
+ if self.SINGLE_BONE:
+ align_bone_z_axis(self.obj, mch_ctrl_name, eb[b].z_axis)
+
+ mch_ctrl += [mch_ctrl_name]
+
+ return {
+ 'mch' : mch,
+ 'mch_ctrl' : mch_ctrl,
+ 'mch_auto' : mch_auto,
+ 'tweak' : twk,
+ 'ctrl' : ctrl,
+ 'conv' : conv_twk
+ }
+
+ def parent_bones(self, bones):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Parent deform bones
+ for i, b in enumerate(bones['def']):
+ if i > 0: # For all bones but the first (which has no parent)
+ eb[b].parent = eb[bones['def'][i-1]] # to previous
+ eb[b].use_connect = True
+
+ # Todo check case when sup_chain is in bigger rig
+ eb[bones['def'][0]].parent = eb[bones['chain']['mch'][0]]
+
+ for i, twk in enumerate(bones['chain']['tweak']):
+ eb[ twk ].parent = eb[bones['chain']['mch_ctrl'][i+1]]
+ eb[ twk ].use_inherit_scale = False
+
+ eb[bones['chain']['ctrl'][0]].parent = eb[bones['chain']['mch_ctrl'][0]]
+ eb[bones['chain']['ctrl'][0]].use_inherit_scale = False
+ eb[bones['chain']['ctrl'][1]].parent = eb[bones['chain']['mch_ctrl'][-1]]
+ eb[bones['chain']['ctrl'][1]].use_inherit_scale = False
+
+
+ if 'pivot' in bones.keys():
+ eb[ bones['pivot']['ctrl'] ].use_inherit_scale = False
+
+ for i,mch in enumerate( bones['chain']['mch'] ):
+ if mch == bones['chain']['mch'][0]:
+ eb[ mch ].parent = eb[ bones['chain']['ctrl'][0] ]
+ elif mch == bones['chain']['mch'][-1]:
+ eb[ mch ].parent = eb[ bones['chain']['ctrl'][1] ]
+ else:
+ eb[ mch ].parent = eb[ bones['chain']['tweak'][i-1] ]
+
+ if 'parent' in bones.keys():
+ eb[bones['chain']['mch_auto']].parent = eb[bones['parent']]
+ eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['parent']]
+ eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['parent']]
+
+ for i, mch_ctrl in enumerate( bones['chain']['mch_ctrl'][1:-1] ):
+ eb[ mch_ctrl ].parent = eb[ bones['chain']['mch_auto'] ]
+
+ if 'pivot' in bones.keys():
+ eb[ bones['pivot']['ctrl'] ].parent = eb[ bones['chain']['mch_auto'] ]
+
+ if bones['chain']['conv']:
+ eb[ bones['chain']['tweak'][-1] ].parent = eb[ bones['chain']['conv'] ]
+
+ if self.SINGLE_BONE:
+ eb[bones['chain']['ctrl'][0]].parent = None
+ eb[bones['chain']['ctrl'][-1]].parent = None
+ eb[bones['chain']['mch_ctrl'][0]].parent = eb[bones['chain']['ctrl'][0]]
+ eb[bones['chain']['mch_ctrl'][-1]].parent = eb[bones['chain']['ctrl'][-1]]
+ eb[bones['chain']['mch'][0]].parent = eb[bones['chain']['mch'][1]]
+ eb[bones['chain']['mch'][1]].parent = eb[bones['chain']['mch_ctrl'][0]]
+
+ return #TODO modify what follows
+
+ # Parent control bones
+ # Head control => MCH-rotation_head
+ eb[ bones['neck']['ctrl'] ].parent = eb[ bones['neck']['mch_head'] ]
+
+ # MCH stretch => neck ctrl
+ eb[ bones['neck']['mch_str'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
+
+ # Neck control => MCH-rotation_neck
+ eb[ bones['neck']['ctrl_neck'] ].parent = eb[ bones['neck']['mch_neck'] ]
+
+ # Parent hips and chest controls to torso
+ eb[ bones['chest']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
+ eb[ bones['hips']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
+
+ # Parent mch bones
+ # Neck mch
+ eb[ bones['neck']['mch_head'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
+
+ parent = eb[ bones['neck']['mch_str'] ]
+ for i,b in enumerate([ eb[n] for n in bones['neck']['mch'] ]):
+ b.parent = parent
+
+ # Chest mch bones and neck mch
+ chest_mch = bones['chest']['mch'] + [ bones['neck']['mch_neck'] ]
+ for i,b in enumerate(chest_mch):
+ if i == 0:
+ eb[b].parent = eb[ bones['pivot']['ctrl'] ]
+ else:
+ eb[b].parent = eb[ chest_mch[i-1] ]
+
+ # Hips mch bones
+ for i,b in enumerate( bones['hips']['mch'] ):
+ if i == len(bones['hips']['mch']) - 1:
+ eb[b].parent = eb[ bones['pivot']['ctrl'] ]
+ else:
+ eb[b].parent = eb[ bones['hips']['mch'][i+1] ]
+
+ # mch pivot
+ eb[ bones['pivot']['mch'] ].parent = eb[ bones['chest']['mch'][0] ]
+
+ # MCH widgets
+ eb[ bones['chest']['mch_wgt'] ].parent = eb[ bones['chest']['mch'][-1] ]
+ eb[ bones['hips' ]['mch_wgt'] ].parent = eb[ bones['hips' ]['mch'][0 ] ]
+
+ # Tweaks
+
+ # Neck tweaks
+ for i,twk in enumerate( bones['neck']['tweak'] ):
+ if i == 0:
+ eb[ twk ].parent = eb[ bones['neck']['ctrl_neck'] ]
+ else:
+ eb[ twk ].parent = eb[ bones['neck']['mch'][i-1] ]
+
+ # Chest tweaks
+ for twk,mch in zip( bones['chest']['tweak'], bones['chest']['mch'] ):
+ if bones['chest']['tweak'].index( twk ) == 0:
+ eb[ twk ].parent = eb[ bones['pivot']['mch'] ]
+ else:
+ eb[ twk ].parent = eb[ mch ]
+
+ # Hips tweaks
+ for i,twk in enumerate(bones['hips']['tweak']):
+ if i == 0:
+ eb[twk].parent = eb[ bones['hips']['mch'][i] ]
+ else:
+ eb[twk].parent = eb[ bones['hips']['mch'][i-1] ]
+
+ # Parent orgs to matching tweaks
+ tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
+
+ if 'tail' in bones.keys():
+ tweaks += bones['tail']['tweak']
+
+ for org, twk in zip( org_bones, tweaks ):
+ eb[ org ].parent = eb[ twk ]
+
+ def make_constraint(self, bone, constraint):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pb = self.obj.pose.bones
+
+ owner_pb = pb[bone]
+ const = owner_pb.constraints.new(constraint['constraint'])
+ const.target = self.obj
+
+ # filter contraint props to those that actually exist in the current
+ # type of constraint, then assign values to each
+ for p in [k for k in constraint.keys() if k in dir(const)]:
+ setattr(const, p, constraint[p])
+
+ def constrain_bones(self, bones):
+ # DEF bones
+
+ deform = bones['def']
+ mch = bones['chain']['mch']
+ mch_ctrl = bones['chain']['mch_ctrl']
+ ctrls = bones['chain']['ctrl']
+ tweaks = [ ctrls[0]] + bones['chain']['tweak'] + [ ctrls[-1] ]
+
+ # if 'conv' in bones['chain'].keys():
+ # conv_tweak = bones['chain']['conv']
+
+ for i, d in enumerate(deform):
+
+ if len(deform) > 1:
+ self.make_constraint(d, {
+ 'constraint': 'COPY_TRANSFORMS',
+ 'subtarget': mch[i],
+ 'owner_space': 'POSE',
+ 'target_space': 'POSE'
+ })
+
+ self.make_constraint(d, {
+ 'constraint': 'STRETCH_TO',
+ 'subtarget': tweaks[i+1]
+ })
+
+ if 'pivot' in bones.keys():
+ step = 2/(len(self.org_bones))
+ for i,b in enumerate(mch_ctrl):
+ xval = i*step
+ influence = 2*xval - xval**2 #parabolic influence of pivot
+ if (i != 0) and (i != len(mch_ctrl)-1):
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : bones['pivot']['ctrl'],
+ 'influence' : influence,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ # MCH-AUTO
+
+ mch_auto = bones['chain']['mch_auto']
+
+ if mch_auto:
+ self.make_constraint( mch_auto, {
+ 'constraint': 'COPY_LOCATION',
+ 'subtarget' : mch[0],
+ 'owner_space' : 'WORLD',
+ 'target_space' : 'WORLD'
+ } )
+
+ self.make_constraint( mch_auto, {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : tweaks[-1]
+ } )
+
+ # PIVOT CTRL
+
+ if 'pivot' in bones.keys():
+
+ pivot = bones['pivot']['ctrl']
+
+ self.make_constraint( pivot, {
+ 'constraint': 'COPY_ROTATION',
+ 'subtarget' : tweaks[0],
+ 'influence' : 0.33,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ self.make_constraint( pivot, {
+ 'constraint': 'COPY_ROTATION',
+ 'subtarget' : tweaks[-1],
+ 'influence' : 0.33,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+ # MCH-CTRL
+
+ # for i, b in enumerate(mch_ctrl):
+ #
+ # if i != 0 and mch_ctrl[i] != mch_ctrl[-1]:
+ # self.make_constraint( b, {
+ # 'constraint' : 'COPY_TRANSFORMS',
+ # 'subtarget' : tweaks[i-1],
+ # 'influence' : 0.5,
+ # 'owner_space' : 'LOCAL',
+ # 'target_space' : 'LOCAL'
+ # } )
+ #
+ # self.make_constraint( b, {
+ # 'constraint' : 'COPY_TRANSFORMS',
+ # 'subtarget' : tweaks[i+1],
+ # 'influence' : 0.5,
+ # 'owner_space' : 'LOCAL',
+ # 'target_space' : 'LOCAL'
+ # } )
+
+ return #Todo mdify what follows
+
+ # head and neck MCH bones
+ for b in [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]:
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_ROTATION',
+ 'subtarget' : bones['pivot']['ctrl'],
+ } )
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_SCALE',
+ 'subtarget' : bones['pivot']['ctrl'],
+ } )
+
+ # Neck MCH Stretch
+ self.make_constraint( bones['neck']['mch_str'], {
+ 'constraint' : 'DAMPED_TRACK',
+ 'subtarget' : bones['neck']['ctrl'],
+ })
+
+ self.make_constraint( bones['neck']['mch_str'], {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : bones['neck']['ctrl'],
+ })
+
+ # Intermediary mch bones
+ intermediaries = [ bones['neck'], bones['chest'], bones['hips'] ]
+
+ if 'tail' in bones.keys():
+ intermediaries += bones['tail']
+
+ for i,l in enumerate(intermediaries):
+ mch = l['mch']
+ factor = float( 1 / len( l['tweak'] ) )
+
+ for j,b in enumerate(mch):
+ if i == 0:
+ nfactor = float( (j + 1) / len( mch ) )
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_ROTATION',
+ 'subtarget' : l['ctrl'],
+ 'influence' : nfactor
+ } )
+ else:
+ self.make_constraint( b, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : l['ctrl'],
+ 'influence' : factor,
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ } )
+
+
+ # MCH pivot
+ self.make_constraint( bones['pivot']['mch'], {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : bones['hips']['mch'][-1],
+ 'owner_space' : 'LOCAL',
+ 'target_space' : 'LOCAL'
+ })
+
+ # DEF bones
+ deform = bones['def']
+ tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
+
+ for d,t in zip(deform, tweaks):
+ tidx = tweaks.index(t)
+
+ self.make_constraint( d, {
+ 'constraint' : 'COPY_TRANSFORMS',
+ 'subtarget' : t
+ })
+
+ if tidx != len(tweaks) - 1:
+ self.make_constraint( d, {
+ 'constraint' : 'DAMPED_TRACK',
+ 'subtarget' : tweaks[ tidx + 1 ],
+ })
+
+ self.make_constraint( d, {
+ 'constraint' : 'STRETCH_TO',
+ 'subtarget' : tweaks[ tidx + 1 ],
+ })
+
+ def stick_to_bendy_bones(self, bones):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ deform = bones['def']
+ pb = self.obj.pose.bones
+
+ if len(deform) > 1: # Only for single bone sup chain
+ return
+
+ def_pb = pb[deform[0]]
+ ctrl_start = pb[bones['chain']['ctrl'][0]]
+ ctrl_end = pb[bones['chain']['ctrl'][-1]]
+ mch_start = pb[bones['chain']['mch'][0]]
+ mch_end = pb[bones['chain']['mch_ctrl'][-1]]
+
+ if 'bbone_custom_handle_start' in dir(def_pb) and 'bbone_custom_handle_end' in dir(def_pb):
+ if not self.SINGLE_BONE:
+ def_pb.bbone_custom_handle_start = ctrl_start
+ def_pb.bbone_custom_handle_end = ctrl_end
+ else:
+ def_pb.bbone_custom_handle_start = mch_start
+ def_pb.bbone_custom_handle_end = mch_end
+ def_pb.use_bbone_custom_handles = True
+
+ def create_drivers(self, bones):
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ pb = self.obj.pose.bones
+
+ # Setting the torso's props
+ torso = pb[ bones['pivot']['ctrl'] ]
+
+ props = [ "head_follow", "neck_follow" ]
+ owners = [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]
+
+ for prop in props:
+ if prop == 'neck_follow':
+ torso[prop] = 0.5
+ else:
+ torso[prop] = 0.0
+
+ prop = rna_idprop_ui_prop_get( torso, prop, create=True )
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["description"] = prop
+
+ # driving the follow rotation switches for neck and head
+ for bone, prop, in zip( owners, props ):
+ # Add driver to copy rotation constraint
+ drv = pb[ bone ].constraints[ 0 ].driver_add("influence").driver
+ drv.type = 'AVERAGE'
+
+ var = drv.variables.new()
+ var.name = prop
+ var.type = "SINGLE_PROP"
+ var.targets[0].id = self.obj
+ var.targets[0].data_path = \
+ torso.path_from_id() + '['+ '"' + prop + '"' + ']'
+
+ drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
+
+ drv_modifier.mode = 'POLYNOMIAL'
+ drv_modifier.poly_order = 1
+ drv_modifier.coefficients[0] = 1.0
+ drv_modifier.coefficients[1] = -1.0
+
+ def locks_and_widgets(self, bones):
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pb = self.obj.pose.bones
+
+ #Locks
+ mch_ctrl = bones['chain']['mch_ctrl']
+
+ for b in mch_ctrl:
+ pb[b].lock_rotation = False, False, False
+ pb[b].lock_location = False, False, False
+ pb[b].lock_scale = False, False, False
+
+ for b in bones['chain']['tweak']:
+ pb[b].lock_rotation = True, False, True
+
+ for b in bones['chain']['ctrl']:
+ pb[b].lock_rotation = True, False, True
+
+ if 'pivot' in bones.keys():
+ pb[bones['pivot']['ctrl']].lock_rotation = True, False, True
+
+ # Assigning a widget to main ctrl bone
+ if 'pivot' in bones.keys():
+ create_cube_widget(
+ self.obj,
+ bones['pivot']['ctrl'],
+ radius = 0.15,
+ bone_transform_name = None
+ )
+
+ for bone in bones['chain']['tweak']:
+ create_cube_widget(
+ self.obj,
+ bone,
+ radius = 0.2,
+ bone_transform_name = None
+ )
+
+ create_chain_widget(
+ self.obj,
+ bones['chain']['ctrl'][0],
+ invert = False,
+ radius = 0.3,
+ bone_transform_name = None
+ )
+
+ create_chain_widget(
+ self.obj,
+ bones['chain']['ctrl'][-1],
+ invert = True,
+ radius = 0.3,
+ bone_transform_name = None
+ )
+
+ if bones['chain']['conv']:
+ create_cube_widget(
+ self.obj,
+ bones['chain']['conv'],
+ radius = 0.5,
+ bone_transform_name = None
+ )
+
+ # Assigning layers to tweaks and ctrls
+ for bone in bones['chain']['tweak']:
+ if self.tweak_layers:
+ pb[bone].bone.layers = self.tweak_layers
+
+ # for bone in bones['chain']['ctrl']:
+ # if self.tweak_layers:
+ # pb[bone].bone.layers = self.tweak_layers
+
+
+ return
+
+
+ # Locks
+ tweaks = bones['neck']['tweak'] + bones['chest']['tweak']
+ tweaks += bones['hips']['tweak']
+
+ if 'tail' in bones.keys():
+ tweaks += bones['tail']['tweak']
+
+ # Tweak bones locks
+ for bone in tweaks:
+ pb[bone].lock_rotation = True, False, True
+ pb[bone].lock_scale = False, True, False
+
+ # Widgets
+
+ # Assigning a widget to pivot bone
+ if 'pivot' in bones.keys():
+ create_cube_widget(
+ self.obj,
+ bones['pivot']['ctrl'],
+ radius = 0.5,
+ bone_transform_name = None
+ )
+
+ # Assigning widgets to control bones
+ gen_ctrls = [
+ bones['neck']['ctrl_neck'],
+ bones['chest']['ctrl'],
+ bones['hips']['ctrl']
+ ]
+
+ if 'tail' in bones.keys():
+ gen_ctrls += [ bones['tail']['ctrl'] ]
+
+ for bone in gen_ctrls:
+ create_circle_widget(
+ self.obj,
+ bone,
+ radius = 1.0,
+ head_tail = 0.5,
+ with_line = False,
+ bone_transform_name = None
+ )
+
+ # Head widget
+ create_circle_widget(
+ self.obj,
+ bones['neck']['ctrl'],
+ radius = 0.75,
+ head_tail = 1.0,
+ with_line = False,
+ bone_transform_name = None
+ )
+
+ # place widgets on correct bones
+ chest_widget_loc = pb[ bones['chest']['mch_wgt'] ]
+ pb[bones['chest']['ctrl'] ].custom_shape_transform = chest_widget_loc
+
+ hips_widget_loc = pb[bones['hips']['mch_wgt']]
+ if 'tail' in bones.keys():
+ hips_widget_loc = bones['def'][self.tail_pos - 1]
+
+ pb[ bones['hips']['ctrl'] ].custom_shape_transform = hips_widget_loc
+
+ # Assigning widgets to tweak bones and layers
+ for bone in tweaks:
+ create_sphere_widget(self.obj, bone, bone_transform_name=None)
+
+ if self.tweak_layers:
+ pb[bone].bone.layers = self.tweak_layers
+
+ def generate(self):
+
+ # Torso Rig Anatomy:
+ # Neck: all bones above neck point, last bone is head
+ # Upper torso: all bones between pivot and neck start
+ # Lower torso: all bones below pivot until tail point
+ # Tail: all bones below tail point
+
+ #bone_chains = self.build_bone_structure()
+
+ self.SINGLE_BONE = (len(self.org_bones) == 1)
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ bones = {}
+ if eb[self.org_bones[0]].parent:
+ bones['parent'] = eb[self.org_bones[0]].parent.name
+
+ # Clear parents for org bones
+ for bone in self.org_bones[0:]:
+ eb[bone].use_connect = False
+ eb[bone].parent = None
+
+ #if bone_chains != 'ERROR':
+ #
+ # # Create lists of bones and strip "ORG" from their names
+ # neck_bones = [ strip_org(b) for b in bone_chains['neck' ] ]
+ # upper_torso_bones = [ strip_org(b) for b in bone_chains['upper'] ]
+ # lower_torso_bones = [ strip_org(b) for b in bone_chains['lower'] ]
+ # tail_bones = [ strip_org(b) for b in bone_chains['tail' ] ]
+
+ chain_bones = [strip_org(b) for b in self.org_bones]
+
+ # bones = {}
+ #
+ # bones['def'] = self.create_deform() # Gets org bones from self
+ # bones['pivot'] = self.create_pivot( self.pivot_pos )
+ # bones['neck'] = self.create_neck( neck_bones )
+ # bones['chest'] = self.create_chest( upper_torso_bones )
+ # bones['hips'] = self.create_hips( lower_torso_bones )
+ # # TODO: Add create tail
+ #
+ # if tail_bones:
+ # bones['tail'] = self.create_tail( tail_bones )
+
+
+
+ bones['def'] = self.create_deform()
+ if len(self.org_bones) > 2:
+ bones['pivot'] = self.create_pivot()
+ bones['chain'] = self.create_chain()
+
+ # Adjust Roll in SINGLE_BONE case
+ #if self.SINGLE_BONE:
+ all_bones = bones['chain']['mch'] + bones['chain']['mch_ctrl'] + bones['chain']['ctrl'] + bones['def']
+ for b in all_bones:
+ eb[b].roll = -pi / 2
+
+ #Todo create pivot-like controls
+
+ # # TEST
+ # bpy.ops.object.mode_set(mode ='EDIT')
+ # eb = self.obj.data.edit_bones
+ #
+ # self.parent_bones( bones )
+ # self.constrain_bones( bones )
+ # self.create_drivers( bones )
+ # self.locks_and_widgets( bones )
+
+ self.parent_bones(bones)
+ self.constrain_bones(bones)
+ self.stick_to_bendy_bones(bones)
+ self.locks_and_widgets(bones)
+
+ #Todo invoke the remaining functions
+
+ # controls = [ bones['neck']['ctrl'], bones['neck']['ctrl_neck'] ]
+ # controls += [ bones['chest']['ctrl'], bones['hips']['ctrl'] ]
+ # controls += [ bones['pivot']['ctrl'] ]
+
+ # if 'tail' in bones.keys():
+ # controls += [ bones['tail']['ctrl'] ]
+
+ return #TODO modify what follows
+
+ # Create UI
+ controls_string = ", ".join(["'" + x + "'" for x in controls]) #TODO correct this
+ return [script % (
+ controls_string,
+ bones['pivot']['ctrl'],
+ 'head_follow',
+ 'neck_follow'
+ )]
+
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+
+ items = [
+ ('auto', 'Auto', ''),
+ ('x', 'X', ''),
+ ('y', 'Y', ''),
+ ('z', 'Z', '')
+ ]
+
+ params.tweak_axis = bpy.props.EnumProperty(
+ items = items,
+ name = "Tweak Axis",
+ default = 'auto'
+ )
+
+ params.conv_bone = bpy.props.StringProperty(
+ name = 'Convergence bone',
+ default = ''
+ )
+
+ params.bbones = bpy.props.IntProperty(
+ name = 'bbone segments',
+ default = 10,
+ min = 1,
+ description = 'Number of segments'
+ )
+
+ # params.neck_pos = bpy.props.IntProperty(
+ # name = 'neck_position',
+ # default = 6,
+ # min = 0,
+ # description = 'Neck start position'
+ # )
+ #
+ # params.pivot_pos = bpy.props.IntProperty(
+ # name = 'pivot_position',
+ # default = 3,
+ # min = 0,
+ # description = 'Position of the torso control and pivot point'
+ # )
+ #
+ # params.tail_pos = bpy.props.IntProperty(
+ # name = 'tail_position',
+ # default = 0,
+ # min = 0,
+ # description = 'Where the tail starts (change from 0 to enable)'
+ # )
+
+ # Setting up extra layers for the FK and tweak
+ params.tweak_extra_layers = bpy.props.BoolProperty(
+ name = "tweak_extra_layers",
+ default = True,
+ description = ""
+ )
+
+ params.tweak_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters."""
+
+ # r = layout.row()
+ # r.prop(params, "neck_pos")
+ #
+ # r = layout.row()
+ # r.prop(params, "pivot_pos")
+ #
+ # r = layout.row()
+ # r.prop(params, "tail_pos")
+
+ # r = layout.row()
+ # r.prop(params, "control_num")
+
+ pb = bpy.context.object.pose
+
+ r = layout.row()
+ col = r.column(align=True)
+ row = col.row(align=True)
+ row.prop(params, "tweak_axis", expand=True)
+ # for i,axis in enumerate( [ 'x', 'y', 'z' ] ):
+ # row.prop(params, "tweak_axis", index=i, toggle=True, text=axis)
+
+ r = layout.row()
+ r.prop(params, "bbones")
+
+ r = layout.row()
+ r.prop_search(params, 'conv_bone', pb, "bones", text="Convergence Bone")
+
+ r = layout.row()
+ r.prop(params, "tweak_extra_layers")
+ r.active = params.tweak_extra_layers
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range(8):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range(16,24):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range(8,16):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range(24,32):
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('spine')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.5000/8, 1.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['spine'] = bone.name
+ bone = arm.edit_bones.new('spine.001')
+ bone.head[:] = 0.0000, 0.5000/8, 1.0000/8
+ bone.tail[:] = 0.0000, 0.7500/8, 2.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine']]
+ bones['spine.001'] = bone.name
+ bone = arm.edit_bones.new('spine.002')
+ bone.head[:] = 0.0000, 0.7500/8, 2.0000/8
+ bone.tail[:] = 0.0000, 0.5000/8, 3.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine.001']]
+ bones['spine.002'] = bone.name
+ bone = arm.edit_bones.new('spine.003')
+ bone.head[:] = 0.0000, 0.5000/8, 3.0000/8
+ bone.tail[:] = 0.0000, 0.0000, 4.0000/8
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['spine.002']]
+ bones['spine.003'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['spine']]
+ pbone.rigify_type = 'experimental.super_chain'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ pbone = obj.pose.bones[bones['spine.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone.bone.layers = [True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
+
+ arm.layers = [(x in [0]) for x in range(32)] \ No newline at end of file
diff --git a/rigify/rigs/pitchipoy/__init__.py b/rigify/rigs/experimental/super_eye.py
index e69de29b..e69de29b 100644
--- a/rigify/rigs/pitchipoy/__init__.py
+++ b/rigify/rigs/experimental/super_eye.py
diff --git a/rigify/rigs/pitchipoy/limbs/__init__.py b/rigify/rigs/faces/__init__.py
index e69de29b..e69de29b 100644
--- a/rigify/rigs/pitchipoy/limbs/__init__.py
+++ b/rigify/rigs/faces/__init__.py
diff --git a/rigify/rigs/pitchipoy/super_face.py b/rigify/rigs/faces/super_face.py
index 341596a1..ae12ecf6 100755..100644
--- a/rigify/rigs/pitchipoy/super_face.py
+++ b/rigify/rigs/faces/super_face.py
@@ -5,7 +5,7 @@ from ...utils import org, strip_org, make_deformer_name, connected_child
from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_cube_widget
from ...utils import MetarigError
from rna_prop_ui import rna_idprop_ui_prop_get
-from .super_widgets import create_face_widget, create_eye_widget, create_eyes_widget, create_ear_widget, create_jaw_widget, create_teeth_widget
+from ..widgets import create_face_widget, create_eye_widget, create_eyes_widget, create_ear_widget, create_jaw_widget, create_teeth_widget
script = """
@@ -17,18 +17,20 @@ 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:
+
+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 +42,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
@@ -55,25 +57,25 @@ class Rig:
else:
self.secondary_layers = None
- def symmetrical_split( self, bones ):
+ 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 ):
+
+ def create_deformation(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
-
+
def_bones = []
for org in org_bones:
if 'face' in org or 'teeth' in org or 'eye' in org:
@@ -97,68 +99,68 @@ 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 }
-
- def create_ctrl( self, bones ):
+ def create_ctrl(self, bones):
org_bones = self.org_bones
## create control bones
- bpy.ops.object.mode_set(mode ='EDIT')
+ 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] ]
+ eyeL_ctrl_name = strip_org(bones['eyes'][0])
+ eyeR_ctrl_name = strip_org(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 = 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_name = strip_org( bones['eyes'][0] )
- eyeR_ctrl_name = strip_org( bones['eyes'][1] )
+ eyeL_ctrl_e = eb[eyeL_ctrl_name]
+ eyeR_ctrl_e = eb[eyeR_ctrl_name]
+ eyes_ctrl_e = eb['eyes']
- 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' )
+ # eyes ctrls
+ eyeL_e = eb[bones['eyes'][0]]
+ eyeR_e = eb[bones['eyes'][1]]
- eyeL_ctrl_e = eb[ eyeL_ctrl_name ]
- eyeR_ctrl_e = eb[ eyeR_ctrl_name ]
- eyes_ctrl_e = eb[ 'eyes' ]
+ 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, eye_length * 0.75 ] )
+ # 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,
+ 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 +173,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 +205,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 ],
@@ -231,8 +233,7 @@ class Rig:
'nose' : [ master_nose ]
}
-
- def create_tweak( self, bones, uniques, tails ):
+ def create_tweak(self, bones, uniques, tails):
org_bones = self.org_bones
## create tweak bones
@@ -240,7 +241,7 @@ class Rig:
eb = self.obj.data.edit_bones
tweaks = []
-
+
for bone in bones + list( uniques.keys() ):
tweak_name = strip_org( bone )
@@ -273,21 +274,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,11 +298,10 @@ class Rig:
if self.secondary_layers:
pb[bone].bone.layers = self.secondary_layers
create_face_widget( self.obj, bone )
-
+
return { 'all' : tweaks }
-
- def all_controls( self ):
+ def all_controls(self):
org_bones = self.org_bones
org_tongue_bones = sorted([ bone for bone in org_bones if 'tongue' in bone ])
@@ -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 ):
+ 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 ):
+
+ 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,13 @@ 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 ):
+ 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 +648,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 +683,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 +691,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 +720,17 @@ 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 +778,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 +827,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 +851,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 +870,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 +879,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 +887,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'] )
@@ -903,18 +901,17 @@ class Rig:
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
@@ -927,33 +924,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,34 +964,33 @@ 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 )
-
+ 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:
@@ -1002,23 +998,23 @@ class Rig:
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 +1022,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 +1037,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 +1051,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="")
@@ -1720,7 +1716,7 @@ def create_sample(obj):
bpy.ops.object.mode_set(mode='OBJECT')
pbone = obj.pose.bones[bones['face']]
- pbone.rigify_type = 'pitchipoy.super_face'
+ pbone.rigify_type = 'faces.super_face'
pbone.lock_location = (False, False, False)
pbone.lock_rotation = (False, False, False)
pbone.lock_rotation_w = False
@@ -2381,10 +2377,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/finger.py b/rigify/rigs/finger.py
deleted file mode 100644
index 70bbc112..00000000
--- a/rigify/rigs/finger.py
+++ /dev/null
@@ -1,411 +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 rna_prop_ui import rna_idprop_ui_prop_get
-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
-
-
-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
- prop = rna_idprop_ui_prop_get(pb[ctrl], prop_name, create=True)
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- if i == 1:
- pb[ctrl][prop_name] = 0.0
- else:
- pb[ctrl][prop_name] = val
-
- # 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
diff --git a/rigify/rigs/limbs/__init__.py b/rigify/rigs/limbs/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rigify/rigs/limbs/__init__.py
diff --git a/rigify/rigs/pitchipoy/limbs/super_arm.py b/rigify/rigs/limbs/arm.py
index 1f84c6d5..1a560c46 100644
--- a/rigify/rigs/pitchipoy/limbs/super_arm.py
+++ b/rigify/rigs/limbs/arm.py
@@ -1,16 +1,17 @@
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]
@@ -18,24 +19,30 @@ 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
index 06df1c74..e60f2c68 100644
--- a/rigify/rigs/pitchipoy/limbs/super_leg.py
+++ b/rigify/rigs/limbs/leg.py
@@ -1,20 +1,18 @@
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]
@@ -22,24 +20,30 @@ 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/pitchipoy/limbs/limb_utils.py b/rigify/rigs/limbs/limb_utils.py
index ce6a0761..111a7d1c 100644
--- a/rigify/rigs/pitchipoy/limbs/limb_utils.py
+++ b/rigify/rigs/limbs/limb_utils.py
@@ -1,19 +1,19 @@
import bpy, re
from mathutils import Vector
-from ....utils import org, strip_org, make_mechanism_name, make_deformer_name
-from ....utils import MetarigError
+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
+ 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 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" % (
+ "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/super_front_paw.py b/rigify/rigs/limbs/paw.py
index 04e6280f..c01f2f0d 100644
--- a/rigify/rigs/pitchipoy/limbs/super_front_paw.py
+++ b/rigify/rigs/limbs/paw.py
@@ -1,20 +1,16 @@
-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]
@@ -22,24 +18,30 @@ 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 00000000..462143f6
--- /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/pitchipoy/simple_tentacle.py b/rigify/rigs/limbs/simple_tentacle.py
index 9351a659..d7457c58 100644
--- a/rigify/rigs/pitchipoy/simple_tentacle.py
+++ b/rigify/rigs/limbs/simple_tentacle.py
@@ -1,33 +1,33 @@
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 ...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:
+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
-
+ self.copy_rotation_axes = params.copy_rotation_axes
+
if params.tweak_extra_layers:
- self.tweak_layers = list( params.tweak_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))
+ "RIGIFY ERROR: invalid rig structure on bone: %s" % (strip_org(bone_name))
)
-
- def make_controls( self ):
-
+ 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,11 @@ 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 ):
-
+ def make_tweaks(self):
+
bpy.ops.object.mode_set(mode ='EDIT')
eb = self.obj.data.edit_bones
org_bones = self.org_bones
@@ -67,19 +66,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 +101,11 @@ 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 ):
-
+ def make_deform(self):
+
bpy.ops.object.mode_set(mode ='EDIT')
org_bones = self.org_bones
@@ -116,18 +114,17 @@ 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 ):
-
+ 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 +133,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 +142,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 +154,14 @@ 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 ]
-
-
- def make_constraints( self, all_bones ):
+ 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,30 +171,28 @@ 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')
- con.target = self.obj
- con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ]
- for i, prop in enumerate( [ 'use_x', 'use_y', 'use_z' ] ):
- if self.copy_rotaion_axes[i]:
- setattr( con, prop, True )
+ 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
+ setattr(con, prop, False)
+ con.use_offset = True
con.target_space = 'LOCAL'
- con.owner_space = 'LOCAL'
-
-
+ con.owner_space = 'LOCAL'
def generate(self):
bpy.ops.object.mode_set(mode ='EDIT')
@@ -208,7 +202,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,24 +213,24 @@ class Rig:
'tweak' : tweak_chain,
'deform' : def_chain
}
-
- self.make_constraints( all_bones )
- self.parent_bones( all_bones )
+
+ self.make_constraints(all_bones)
+ self.parent_bones(all_bones)
def add_parameters(params):
""" Add the parameters of this rig type to the
RigifyParameters PropertyGroup
"""
- params.copy_rotaion_axes = bpy.props.BoolVectorProperty(
- size = 3,
- description = "Layers for the tweak controls to be on",
- default = tuple( [ i == 0 for i in range(0, 3) ] )
+ 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",
+ params.tweak_extra_layers = bpy.props.BoolProperty(
+ name = "tweak_extra_layers",
default = True,
description = ""
)
@@ -256,12 +250,12 @@ def parameters_ui(layout, params):
col = r.column(align=True)
row = col.row(align=True)
for i,axis in enumerate( [ 'x', 'y', 'z' ] ):
- row.prop(params, "copy_rotaion_axes", index=i, toggle=True, text=axis)
+ 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)
@@ -271,19 +265,20 @@ 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 +292,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 +300,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,10 +308,10 @@ 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'
+ 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/super_finger.py b/rigify/rigs/limbs/super_finger.py
index 6a9c5f09..60645372 100644
--- a/rigify/rigs/pitchipoy/super_finger.py
+++ b/rigify/rigs/limbs/super_finger.py
@@ -13,59 +13,59 @@ if is_selected(controls):
layout.prop(pose_bones[master_name], '["%s"]', text="Curvature", slider=True)
"""
-class Rig:
+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,7 +292,7 @@ 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)
@@ -301,8 +301,8 @@ class Rig:
["'" + 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')
@@ -363,7 +363,7 @@ def create_sample(obj):
pbone.lock_scale = (False, False, False)
pbone.rotation_mode = 'YXZ'
pbone = obj.pose.bones[bones['f_pinky.01.L']]
- pbone.rigify_type = 'pitchipoy.simple_tentacle'
+ pbone.rigify_type = 'limbs.simple_tentacle'
pbone.lock_location = (False, False, False)
pbone.lock_rotation = (False, False, False)
pbone.lock_rotation_w = False
@@ -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/limbs/super_limb.py b/rigify/rigs/limbs/super_limb.py
new file mode 100644
index 00000000..8400ea24
--- /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/pitchipoy/super_palm.py b/rigify/rigs/limbs/super_palm.py
index 68d38958..efcb5681 100755..100644
--- a/rigify/rigs/pitchipoy/super_palm.py
+++ b/rigify/rigs/limbs/super_palm.py
@@ -123,9 +123,13 @@ class Rig:
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[def_parent]
- eb[ctrl].parent = eb[def_parent]
+ eb[o].parent = eb[parent_to]
+ eb[ctrl].parent = eb[parent_to]
# Constraints
bpy.ops.object.mode_set(mode='OBJECT')
@@ -145,7 +149,7 @@ class Rig:
con = pb[b].constraints.new('COPY_SCALE')
con.name = "copy_scale"
con.target = self.obj
- con.subtarget = def_parent
+ con.subtarget = parent_to
con.target_space = 'WORLD'
con.owner_space = 'WORLD'
con.influence = 1
diff --git a/rigify/rigs/pitchipoy/limbs/ui.py b/rigify/rigs/limbs/ui.py
index a7ed95a7..948b5719 100644
--- a/rigify/rigs/pitchipoy/limbs/ui.py
+++ b/rigify/rigs/limbs/ui.py
@@ -4,10 +4,12 @@ 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 )
+ 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]
@@ -22,22 +24,24 @@ if is_selected( controls ):
props.uarm_ik = controls[0]
props.farm_ik = ik_ctrl[1]
props.hand_ik = controls[4]
- props.pole = ""
+ 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 on IK Control bone
-if is_selected( ik_ctrl ):
+
+# 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 ):
+if is_selected( fk_ctrl ) or is_selected(parent):
layout.prop( pose_bones[ parent ], '["%s"]', slider = True )
-"""
+"""
script_leg = """
controls = [%s]
@@ -45,10 +49,12 @@ 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 )
+ 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]
@@ -66,53 +72,64 @@ if is_selected( controls ):
props.thigh_ik = controls[0]
props.shin_ik = ik_ctrl[1]
props.foot_ik = controls[6]
- props.pole = ""
+ 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 on IK Control bone
-if is_selected( ik_ctrl ):
+# 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 ):
+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']['limb']] + bones['fk']['ctrl']
controls += bones['ik']['ctrl']['terminal']
- controls += [ bones['fk']['mch'] ]
+ 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 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['parent'],
+ bones['main_parent'],
+ bones['fk']['ctrl'][-1],
+ pole,
'IK/FK',
'rubber_tweak',
- 'IK_Strertch',
+ 'IK_Stretch',
+ 'pole_vector',
'FK_limb_follow'
)
@@ -122,10 +139,13 @@ def create_script( bones, limb_type=None):
tweaks_string,
ik_ctrl_string,
bones['fk']['ctrl'][0],
- bones['parent'],
+ bones['main_parent'],
+ bones['fk']['ctrl'][-1],
+ pole,
'IK/FK',
'rubber_tweak',
- 'IK_Strertch',
+ 'IK_Stretch',
+ 'pole_vector',
'FK_limb_follow'
)
@@ -135,9 +155,12 @@ def create_script( bones, limb_type=None):
tweaks_string,
ik_ctrl_string,
bones['fk']['ctrl'][0],
- bones['parent'],
+ bones['main_parent'],
+ bones['fk']['ctrl'][-1],
+ pole,
'IK/FK',
'rubber_tweak',
- 'IK_Strertch',
+ 'IK_Stretch',
+ 'pole_vector',
'FK_limb_follow'
)
diff --git a/rigify/rigs/neck_short.py b/rigify/rigs/neck_short.py
deleted file mode 100644
index 63174d40..00000000
--- a/rigify/rigs/neck_short.py
+++ /dev/null
@@ -1,388 +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 bpy
-from rna_prop_ui import rna_idprop_ui_prop_get
-
-from ..utils import MetarigError
-from ..utils import copy_bone, new_bone, put_bone
-from ..utils import connected_children_names
-from ..utils import strip_org, make_mechanism_name, make_deformer_name
-from ..utils import create_circle_widget
-
-
-script1 = """
-head_neck = ["%s", "%s"]
-"""
-
-script2 = """
-if is_selected(head_neck[0]):
- layout.prop(pose_bones[head_neck[0]], '["isolate"]', text="Isolate (" + head_neck[0] + ")", slider=True)
-"""
-
-script3 = """
-if is_selected(head_neck):
- layout.prop(pose_bones[head_neck[0]], '["neck_follow"]', text="Neck Follow Head (" + head_neck[0] + ")", slider=True)
-"""
-
-
-class Rig:
- """ A "neck" rig. It turns a chain of bones into a rig with two controls:
- One for the head, and one for the neck.
-
- """
- 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
-
- 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)))
-
- self.isolate = False
- if self.obj.data.bones[bone_name].parent:
- self.isolate = True
-
- def gen_deform(self):
- """ Generate the deformation rig.
-
- """
- for name in self.org_bones:
- bpy.ops.object.mode_set(mode='EDIT')
- eb = self.obj.data.edit_bones
-
- # Create deform bone
- bone_e = eb[copy_bone(self.obj, name)]
-
- # Change its name
- bone_e.name = make_deformer_name(strip_org(name))
- bone_name = bone_e.name
-
- # Leave edit mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Get the pose bone
- bone = self.obj.pose.bones[bone_name]
-
- # Constrain to the original bone
- con = bone.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name
-
- def gen_control(self):
- """ Generate the control rig.
-
- """
- #---------------------------------
- # Create the neck and head controls
- bpy.ops.object.mode_set(mode='EDIT')
-
- # Create bones
- neck_ctrl = copy_bone(self.obj, self.org_bones[0], strip_org(self.org_bones[0]))
- neck_follow = copy_bone(self.obj, self.org_bones[-1], make_mechanism_name(strip_org(self.org_bones[0] + ".follow")))
- neck_child = new_bone(self.obj, make_mechanism_name(strip_org(self.org_bones[0] + ".child")))
-
- head_ctrl = copy_bone(self.obj, self.org_bones[-1], strip_org(self.org_bones[-1]))
- head_mch = new_bone(self.obj, make_mechanism_name(strip_org(self.org_bones[-1])))
- if self.isolate:
- head_socket1 = copy_bone(self.obj, self.org_bones[-1], make_mechanism_name(strip_org(self.org_bones[-1] + ".socket1")))
- head_socket2 = copy_bone(self.obj, self.org_bones[-1], make_mechanism_name(strip_org(self.org_bones[-1] + ".socket2")))
-
- # Create neck chain bones
- neck = []
- helpers = []
- for name in self.org_bones:
- neck += [copy_bone(self.obj, name, make_mechanism_name(strip_org(name)))]
- helpers += [copy_bone(self.obj, neck_child, make_mechanism_name(strip_org(name + ".02")))]
-
- # Fetch edit bones
- eb = self.obj.data.edit_bones
-
- neck_ctrl_e = eb[neck_ctrl]
- neck_follow_e = eb[neck_follow]
- neck_child_e = eb[neck_child]
- head_ctrl_e = eb[head_ctrl]
- head_mch_e = eb[head_mch]
- if self.isolate:
- head_socket1_e = eb[head_socket1]
- head_socket2_e = eb[head_socket2]
-
- # Parenting
- head_ctrl_e.use_connect = False
- head_ctrl_e.parent = neck_ctrl_e.parent
- head_mch_e.use_connect = False
- head_mch_e.parent = head_ctrl_e
-
- if self.isolate:
- head_socket1_e.use_connect = False
- head_socket1_e.parent = neck_ctrl_e.parent
-
- head_socket2_e.use_connect = False
- head_socket2_e.parent = None
-
- head_ctrl_e.parent = head_socket2_e
-
- for (name1, name2) in zip(neck, helpers):
- eb[name1].use_connect = False
- eb[name1].parent = eb[name2]
- eb[name2].use_connect = False
- eb[name2].parent = neck_ctrl_e.parent
-
- neck_follow_e.use_connect = False
- neck_follow_e.parent = neck_ctrl_e.parent
- neck_child_e.use_connect = False
- neck_child_e.parent = neck_ctrl_e
- neck_ctrl_e.parent = neck_follow_e
-
- # Position
- put_bone(self.obj, neck_follow, neck_ctrl_e.head)
- put_bone(self.obj, neck_child, neck_ctrl_e.head)
- put_bone(self.obj, head_ctrl, neck_ctrl_e.head)
- put_bone(self.obj, head_mch, neck_ctrl_e.head)
- head_mch_e.length = head_ctrl_e.length / 2
- neck_child_e.length = neck_ctrl_e.length / 2
-
- if self.isolate:
- put_bone(self.obj, head_socket1, neck_ctrl_e.head)
- head_mch_e.length /= 2
-
- put_bone(self.obj, head_socket2, neck_ctrl_e.head)
- head_mch_e.length /= 3
-
- for (name1, name2) in zip(neck, helpers):
- put_bone(self.obj, name2, eb[name1].head)
- eb[name2].length = eb[name1].length / 2
-
- # Switch to object mode
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
- neck_ctrl_p = pb[neck_ctrl]
- neck_follow_p = pb[neck_follow]
- # neck_child_p = pb[neck_child] # UNUSED
- head_ctrl_p = pb[head_ctrl]
- if self.isolate:
- # head_socket1_p = pb[head_socket1] # UNUSED
- head_socket2_p = pb[head_socket2]
-
- # Custom bone appearance
- neck_ctrl_p.custom_shape_transform = pb[self.org_bones[(len(self.org_bones) - 1) // 2]]
- head_ctrl_p.custom_shape_transform = pb[self.org_bones[-1]]
-
- # Custom properties
- prop = rna_idprop_ui_prop_get(head_ctrl_p, "inf_extent", create=True)
- head_ctrl_p["inf_extent"] = 0.5
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- prop = rna_idprop_ui_prop_get(head_ctrl_p, "neck_follow", create=True)
- head_ctrl_p["neck_follow"] = 1.0
- prop["min"] = 0.0
- prop["max"] = 2.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- if self.isolate:
- prop = rna_idprop_ui_prop_get(head_ctrl_p, "isolate", create=True)
- head_ctrl_p["isolate"] = 0.0
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- # Constraints
-
- # Neck follow
- con = neck_follow_p.constraints.new('COPY_ROTATION')
- con.name = "copy_rotation"
- con.target = self.obj
- con.subtarget = head_ctrl
-
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- var.name = "follow"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = head_ctrl_p.path_from_id() + '["neck_follow"]'
- driver.expression = "follow / 2"
-
- # Isolate
- if self.isolate:
- con = head_socket2_p.constraints.new('COPY_LOCATION')
- con.name = "copy_location"
- con.target = self.obj
- con.subtarget = head_socket1
-
- con = head_socket2_p.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = head_socket1
-
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- var.name = "isolate"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = head_ctrl_p.path_from_id() + '["isolate"]'
- driver.expression = "1.0 - isolate"
-
- # Neck chain
- first = True
- prev = None
- i = 0
- l = len(neck)
- for (name1, name2, org_name) in zip(neck, helpers, self.org_bones):
- con = pb[org_name].constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name1
-
- n_con = pb[name2].constraints.new('COPY_TRANSFORMS')
- n_con.name = "neck"
- n_con.target = self.obj
- n_con.subtarget = neck_child
-
- h_con = pb[name2].constraints.new('COPY_TRANSFORMS')
- h_con.name = "head"
- h_con.target = self.obj
- h_con.subtarget = head_mch
-
- con = pb[name2].constraints.new('COPY_LOCATION')
- con.name = "anchor"
- con.target = self.obj
- if first:
- con.subtarget = neck_ctrl
- else:
- con.subtarget = prev
- con.head_tail = 1.0
-
- # Drivers
- n = (i + 1) / l
-
- # Neck influence
- fcurve = n_con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- var.name = "ext"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = head_ctrl_p.path_from_id() + '["inf_extent"]'
- driver.expression = "1.0 if (%.4f > (1.0-ext) or (1.0-ext) == 0.0) else (%.4f / (1.0-ext))" % (n, n)
-
- # Head influence
- if (i + 1) == l:
- h_con.influence = 1.0
- else:
- fcurve = h_con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'SCRIPTED'
- var.name = "ext"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = head_ctrl_p.path_from_id() + '["inf_extent"]'
- driver.expression = "0.0 if (%.4f <= (1.0-ext)) else ((%.4f - (1.0-ext)) / ext)" % (n, n)
-
- first = False
- prev = name1
- i += 1
-
- # Create control widgets
- create_circle_widget(self.obj, neck_ctrl, radius=1.0, head_tail=0.5, bone_transform_name=self.org_bones[(len(self.org_bones) - 1) // 2])
- create_circle_widget(self.obj, head_ctrl, radius=1.0, head_tail=0.5, bone_transform_name=self.org_bones[-1])
-
- # Return control bones
- return (head_ctrl, neck_ctrl)
-
- 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.gen_deform()
- (head, neck) = self.gen_control()
-
- script = script1 % (head, neck)
- if self.isolate:
- script += script2
- script += script3
-
- return [script]
-
-
-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('neck')
- bone.head[:] = 0.0000, 0.0000, 0.0000
- bone.tail[:] = 0.0000, -0.0500, 0.1500
- bone.roll = 0.0000
- bone.use_connect = False
- bones['neck'] = bone.name
- bone = arm.edit_bones.new('head')
- bone.head[:] = 0.0000, -0.0500, 0.1500
- bone.tail[:] = 0.0000, -0.0500, 0.4000
- bone.roll = 3.1416
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['neck']]
- bones['head'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
- 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 = 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'
-
- 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/palm.py b/rigify/rigs/palm.py
deleted file mode 100644
index 6bcaad11..00000000
--- a/rigify/rigs/palm.py
+++ /dev/null
@@ -1,273 +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
-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
-
- for d, b in zip(def_bones, self.org_bones):
- eb[d].use_connect = False
- eb[d].parent = eb[b]
-
- # 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_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.15780271589756012, 2.086162567138672e-07, -0.30000004172325134), (0.15780259668827057, 1.0, -0.2000001072883606), (-0.15780280530452728, 0.9999999403953552, -0.20000004768371582), (-0.15780259668827057, -2.086162567138672e-07, -0.29999998211860657), (-0.15780256688594818, -2.7089754439657554e-07, 0.30000004172325134), (-0.1578027755022049, 0.9999998807907104, 0.19999995827674866), (0.15780262649059296, 0.9999999403953552, 0.19999989867210388), (0.1578027456998825, 1.4633496903115883e-07, 0.29999998211860657), (0.15780268609523773, 0.2500001788139343, -0.27500003576278687), (-0.15780264139175415, 0.24999985098838806, -0.2749999761581421), (0.15780262649059296, 0.7500000596046448, -0.22500008344650269), (-0.1578027606010437, 0.7499998807907104, -0.2250000238418579), (0.15780265629291534, 0.75, 0.22499991953372955), (0.15780271589756012, 0.2500000596046448, 0.2749999761581421), (-0.15780261158943176, 0.2499997615814209, 0.27500003576278687), (-0.1578027307987213, 0.7499998807907104, 0.22499997913837433)]
- if 'Z' in self.palm_rotation_axis:
- # Flip x/z coordinates
- temp = []
- for v in verts:
- temp += [(v[2], v[1], v[0])]
- verts = temp
- 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/pitchipoy/limbs/arm.py b/rigify/rigs/pitchipoy/limbs/arm.py
deleted file mode 100644
index 17bf5535..00000000
--- a/rigify/rigs/pitchipoy/limbs/arm.py
+++ /dev/null
@@ -1,116 +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 bpy
-from ....utils import MetarigError
-from ....utils import create_widget, copy_bone
-from ....utils import strip_org
-from .limb_utils import *
-from ..super_widgets import create_hand_widget
-from rna_prop_ui import rna_idprop_ui_prop_get
-
-def create_arm( cls, bones ):
- org_bones = cls.org_bones
-
- bpy.ops.object.mode_set(mode='EDIT')
- eb = cls.obj.data.edit_bones
-
- ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' )
-
- # Create IK arm control
- ctrl = copy_bone( cls.obj, org_bones[2], ctrl )
-
- # clear parent (so that rigify will parent to root)
- eb[ ctrl ].parent = None
- eb[ ctrl ].use_connect = False
-
- # Parent
- eb[ bones['ik']['mch_target'] ].parent = eb[ ctrl ]
- eb[ bones['ik']['mch_target'] ].use_connect = False
-
- # Set up constraints
- # Constrain mch target bone to the ik control and mch stretch
-
- make_constraint( cls, bones['ik']['mch_target'], {
- 'constraint' : 'COPY_LOCATION',
- 'subtarget' : bones['ik']['mch_str'],
- 'head_tail' : 1.0
- })
-
- # Constrain mch ik stretch bone to the ik control
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : ctrl,
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : ctrl,
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'LIMIT_SCALE',
- 'use_min_y' : True,
- 'use_max_y' : True,
- 'max_y' : 1.05,
- 'owner_space' : 'LOCAL'
- })
-
- pb = cls.obj.pose.bones
-
- # Modify rotation mode for ik and tweak controls
- pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY'
-
- for b in bones['tweak']['ctrl']:
- pb[b].rotation_mode = 'ZXY'
-
- # Create ik/fk switch property
- pb_parent = pb[ bones['parent'] ]
-
- pb_parent['IK_Strertch'] = 1.0
- prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = 'IK Stretch'
-
- # Add driver to limit scale constraint influence
- b = bones['ik']['mch_str']
- drv = pb[b].constraints[-1].driver_add("influence").driver
- drv.type = 'SUM'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = cls.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
- drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
- # Create hand widget
- create_hand_widget(cls.obj, ctrl, bone_transform_name=None)
-
- bones['ik']['ctrl']['terminal'] = [ ctrl ]
-
- return bones
diff --git a/rigify/rigs/pitchipoy/limbs/leg.py b/rigify/rigs/pitchipoy/limbs/leg.py
deleted file mode 100644
index 14fd6f13..00000000
--- a/rigify/rigs/pitchipoy/limbs/leg.py
+++ /dev/null
@@ -1,333 +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 bpy, math
-from ....utils import MetarigError, connected_children_names
-from ....utils import create_widget, copy_bone, create_circle_widget
-from ....utils import strip_org, flip_bone, put_bone
-from rna_prop_ui import rna_idprop_ui_prop_get
-from ..super_widgets import create_foot_widget, create_ballsocket_widget
-from .limb_utils import *
-
-def create_leg( cls, bones ):
- org_bones = list(
- [cls.org_bones[0]] + connected_children_names(cls.obj, cls.org_bones[0])
- )
-
- bones['ik']['ctrl']['terminal'] = []
-
- bpy.ops.object.mode_set(mode='EDIT')
- eb = cls.obj.data.edit_bones
-
- # Create toes def bone
- toes_def = get_bone_name( org_bones[-1], 'def' )
- toes_def = copy_bone( cls.obj, org_bones[-1], toes_def )
-
- eb[ toes_def ].use_connect = False
- eb[ toes_def ].parent = eb[ bones['def'][-1] ]
- eb[ toes_def ].use_connect = True
-
- bones['def'] += [ toes_def ]
-
- # Create IK leg control
- ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' )
- ctrl = copy_bone( cls.obj, org_bones[2], ctrl )
-
- # clear parent (so that rigify will parent to root)
- eb[ ctrl ].parent = None
- eb[ ctrl ].use_connect = False
-
- # Create heel ctrl bone
- heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' )
- heel = copy_bone( cls.obj, org_bones[2], heel )
- orient_bone( cls, eb[ heel ], 'y', 0.5 )
- eb[ heel ].length = eb[ org_bones[2] ].length / 2
-
- # Reset control position and orientation
- l = eb[ ctrl ].length
- orient_bone( cls, eb[ ctrl ], 'y', reverse = True )
- eb[ ctrl ].length = l
-
- # Parent
- eb[ heel ].use_connect = False
- eb[ heel ].parent = eb[ ctrl ]
-
- eb[ bones['ik']['mch_target'] ].parent = eb[ heel ]
- eb[ bones['ik']['mch_target'] ].use_connect = False
-
- # Create foot mch rock and roll bones
-
- # Get the tmp heel (floating unconnected without children)
- tmp_heel = ""
- for b in cls.obj.data.bones[ org_bones[2] ].children:
- if not b.use_connect and not b.children:
- tmp_heel = b.name
-
- # roll1 MCH bone
- roll1_mch = get_bone_name( tmp_heel, 'mch', 'roll' )
- roll1_mch = copy_bone( cls.obj, org_bones[2], roll1_mch )
-
- # clear parent
- eb[ roll1_mch ].use_connect = False
- eb[ roll1_mch ].parent = None
-
- flip_bone( cls.obj, roll1_mch )
-
- # Create 2nd roll mch, and two rock mch bones
- roll2_mch = get_bone_name( tmp_heel, 'mch', 'roll' )
- roll2_mch = copy_bone( cls.obj, org_bones[3], roll2_mch )
-
- eb[ roll2_mch ].use_connect = False
- eb[ roll2_mch ].parent = None
-
- put_bone(
- cls.obj,
- roll2_mch,
- ( eb[ tmp_heel ].head + eb[ tmp_heel ].tail ) / 2
- )
-
- eb[ roll2_mch ].length /= 4
-
- # Rock MCH bones
- rock1_mch = get_bone_name( tmp_heel, 'mch', 'rock' )
- rock1_mch = copy_bone( cls.obj, tmp_heel, rock1_mch )
-
- eb[ rock1_mch ].use_connect = False
- eb[ rock1_mch ].parent = None
-
- orient_bone( cls, eb[ rock1_mch ], 'y', 1.0, reverse = True )
- eb[ rock1_mch ].length = eb[ tmp_heel ].length / 2
-
- rock2_mch = get_bone_name( tmp_heel, 'mch', 'rock' )
- rock2_mch = copy_bone( cls.obj, tmp_heel, rock2_mch )
-
- eb[ rock2_mch ].use_connect = False
- eb[ rock2_mch ].parent = None
-
- orient_bone( cls, eb[ rock2_mch ], 'y', 1.0 )
- eb[ rock2_mch ].length = eb[ tmp_heel ].length / 2
-
- # Parent rock and roll MCH bones
- eb[ roll1_mch ].parent = eb[ roll2_mch ]
- eb[ roll2_mch ].parent = eb[ rock1_mch ]
- eb[ rock1_mch ].parent = eb[ rock2_mch ]
- eb[ rock2_mch ].parent = eb[ ctrl ]
-
- # Constrain rock and roll MCH bones
- make_constraint( cls, roll1_mch, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : heel,
- 'owner_space' : 'LOCAL',
- 'target_space' : 'LOCAL'
- })
- make_constraint( cls, roll1_mch, {
- 'constraint' : 'LIMIT_ROTATION',
- 'use_limit_x' : True,
- 'max_x' : math.radians(360),
- 'owner_space' : 'LOCAL'
- })
- make_constraint( cls, roll2_mch, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : heel,
- 'use_y' : False,
- 'use_z' : False,
- 'invert_x' : True,
- 'owner_space' : 'LOCAL',
- 'target_space' : 'LOCAL'
- })
- make_constraint( cls, roll2_mch, {
- 'constraint' : 'LIMIT_ROTATION',
- 'use_limit_x' : True,
- 'max_x' : math.radians(360),
- 'owner_space' : 'LOCAL'
- })
-
- pb = cls.obj.pose.bones
- for i,b in enumerate([ rock1_mch, rock2_mch ]):
- head_tail = pb[b].head - pb[tmp_heel].head
- if '.L' in b:
- if not i:
- min_y = 0
- max_y = math.radians(360)
- else:
- min_y = math.radians(-360)
- max_y = 0
- else:
- if not i:
- min_y = math.radians(-360)
- max_y = 0
- else:
- min_y = 0
- max_y = math.radians(360)
-
-
- make_constraint( cls, b, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : heel,
- 'use_x' : False,
- 'use_z' : False,
- 'owner_space' : 'LOCAL',
- 'target_space' : 'LOCAL'
- })
- make_constraint( cls, b, {
- 'constraint' : 'LIMIT_ROTATION',
- 'use_limit_y' : True,
- 'min_y' : min_y,
- 'max_y' : max_y,
- 'owner_space' : 'LOCAL'
- })
-
- # Constrain 4th ORG to roll2 MCH bone
- make_constraint( cls, org_bones[3], {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : roll2_mch
- })
-
- # Set up constraints
- # Constrain mch target bone to the ik control and mch stretch
-
- make_constraint( cls, bones['ik']['mch_target'], {
- 'constraint' : 'COPY_LOCATION',
- 'subtarget' : bones['ik']['mch_str'],
- 'head_tail' : 1.0
- })
-
- # Constrain mch ik stretch bone to the ik control
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : roll1_mch,
- 'head_tail' : 1.0
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : roll1_mch,
- 'head_tail' : 1.0
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'LIMIT_SCALE',
- 'use_min_y' : True,
- 'use_max_y' : True,
- 'max_y' : 1.05,
- 'owner_space' : 'LOCAL'
- })
-
- # Modify rotation mode for ik and tweak controls
- pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY'
-
- for b in bones['tweak']['ctrl']:
- pb[b].rotation_mode = 'ZXY'
-
- # Create ik/fk switch property
- pb_parent = pb[ bones['parent'] ]
-
- pb_parent['IK_Strertch'] = 1.0
- prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = 'IK Stretch'
-
- # Add driver to limit scale constraint influence
- b = bones['ik']['mch_str']
- drv = pb[b].constraints[-1].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = cls.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
- drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
- # Create leg widget
- create_foot_widget(cls.obj, ctrl, bone_transform_name=None)
-
- # Create heel ctrl locks
- pb[ heel ].lock_location = True, True, True
- pb[ heel ].lock_rotation = False, False, True
- pb[ heel ].lock_scale = True, True, True
-
- # Add ballsocket widget to heel
- create_ballsocket_widget(cls.obj, heel, bone_transform_name=None)
-
- bpy.ops.object.mode_set(mode='EDIT')
- eb = cls.obj.data.edit_bones
-
- if len( org_bones ) >= 4:
- # Create toes control bone
- toes = get_bone_name( org_bones[3], 'ctrl' )
- toes = copy_bone( cls.obj, org_bones[3], toes )
-
- eb[ toes ].use_connect = False
- eb[ toes ].parent = eb[ org_bones[3] ]
-
- # Constrain toes def bones
- make_constraint( cls, bones['def'][-2], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : toes
- })
- make_constraint( cls, bones['def'][-2], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : toes
- })
-
- make_constraint( cls, bones['def'][-1], {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : toes
- })
-
- # Find IK/FK switch property
- pb = cls.obj.pose.bones
- prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' )
-
- # Add driver to limit scale constraint influence
- b = org_bones[3]
- drv = pb[b].constraints[-1].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = cls.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
- drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
- # Create toe circle widget
- create_circle_widget(cls.obj, toes, radius=0.4, head_tail=0.5)
-
- bones['ik']['ctrl']['terminal'] += [ toes ]
-
- bones['ik']['ctrl']['terminal'] += [ heel, ctrl ]
-
- return bones
diff --git a/rigify/rigs/pitchipoy/limbs/paw.py b/rigify/rigs/pitchipoy/limbs/paw.py
deleted file mode 100644
index 03ccd25f..00000000
--- a/rigify/rigs/pitchipoy/limbs/paw.py
+++ /dev/null
@@ -1,214 +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 bpy
-from ....utils import MetarigError, connected_children_names
-from ....utils import create_widget, copy_bone, create_circle_widget
-from ....utils import strip_org, flip_bone
-from rna_prop_ui import rna_idprop_ui_prop_get
-from ..super_widgets import create_foot_widget, create_ballsocket_widget
-from .limb_utils import *
-
-def create_paw( cls, bones ):
- org_bones = list(
- [cls.org_bones[0]] + connected_children_names(cls.obj, cls.org_bones[0])
- )
-
-
- bones['ik']['ctrl']['terminal'] = []
-
- bpy.ops.object.mode_set(mode='EDIT')
- eb = cls.obj.data.edit_bones
-
- # Create IK paw control
- ctrl = get_bone_name( org_bones[2], 'ctrl', 'ik' )
- ctrl = copy_bone( cls.obj, org_bones[2], ctrl )
-
- # clear parent (so that rigify will parent to root)
- eb[ ctrl ].parent = None
- eb[ ctrl ].use_connect = False
-
- # Create heel control bone
- heel = get_bone_name( org_bones[2], 'ctrl', 'heel_ik' )
- heel = copy_bone( cls.obj, org_bones[2], heel )
-
- # clear parent
- eb[ heel ].parent = None
- eb[ heel ].use_connect = False
-
- # Parent
- eb[ heel ].parent = eb[ ctrl ]
- eb[ heel ].use_connect = False
-
- flip_bone( cls.obj, heel )
-
- eb[ bones['ik']['mch_target'] ].parent = eb[ heel ]
- eb[ bones['ik']['mch_target'] ].use_connect = False
-
- # Reset control position and orientation
- l = eb[ ctrl ].length
- orient_bone( cls, eb[ ctrl ], 'y', reverse = True )
- eb[ ctrl ].length = l
-
- # Set up constraints
- # Constrain mch target bone to the ik control and mch stretch
-
- make_constraint( cls, bones['ik']['mch_target'], {
- 'constraint' : 'COPY_LOCATION',
- 'subtarget' : bones['ik']['mch_str'],
- 'head_tail' : 1.0
- })
-
- # Constrain mch ik stretch bone to the ik control
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : heel,
- 'head_tail' : 1.0
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : heel,
- 'head_tail' : 1.0
- })
- make_constraint( cls, bones['ik']['mch_str'], {
- 'constraint' : 'LIMIT_SCALE',
- 'use_min_y' : True,
- 'use_max_y' : True,
- 'max_y' : 1.05,
- 'owner_space' : 'LOCAL'
- })
-
- pb = cls.obj.pose.bones
-
- # Modify rotation mode for ik and tweak controls
- pb[bones['ik']['ctrl']['limb']].rotation_mode = 'ZXY'
-
- for b in bones['tweak']['ctrl']:
- pb[b].rotation_mode = 'ZXY'
-
- # Create ik/fk switch property
- pb_parent = pb[ bones['parent'] ]
-
- pb_parent['IK_Strertch'] = 1.0
- prop = rna_idprop_ui_prop_get( pb_parent, 'IK_Strertch', create=True )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = 'IK Stretch'
-
- # Add driver to limit scale constraint influence
- b = bones['ik']['mch_str']
- drv = pb[b].constraints[-1].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = cls.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
- drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
- # Create paw widget
- create_foot_widget(cls.obj, ctrl, bone_transform_name=None)
-
- # Create heel ctrl locks
- pb[ heel ].lock_location = True, True, True
-
- # Add ballsocket widget to heel
- create_ballsocket_widget(cls.obj, heel, bone_transform_name=None)
-
- bpy.ops.object.mode_set(mode='EDIT')
- eb = cls.obj.data.edit_bones
-
- if len( org_bones ) >= 4:
- # Create toes control bone
- toes = get_bone_name( org_bones[3], 'ctrl' )
- toes = copy_bone( cls.obj, org_bones[3], toes )
-
- eb[ toes ].use_connect = False
- eb[ toes ].parent = eb[ org_bones[3] ]
-
- # Create toes mch bone
- toes_mch = get_bone_name( org_bones[3], 'mch' )
- toes_mch = copy_bone( cls.obj, org_bones[3], toes_mch )
-
- eb[ toes_mch ].use_connect = False
- eb[ toes_mch ].parent = eb[ ctrl ]
-
- eb[ toes_mch ].length /= 4
-
- # Constrain 4th ORG to toes MCH bone
- make_constraint( cls, org_bones[3], {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : toes_mch
- })
-
- # Constrain toes def bones
-
- make_constraint( cls, bones['def'][-1], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : toes,
- 'head_tail' : 1
- })
- make_constraint( cls, bones['def'][-1], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : toes,
- 'head_tail' : 1
- })
-
-
- # Find IK/FK switch property
- pb = cls.obj.pose.bones
- prop = rna_idprop_ui_prop_get( pb[ bones['parent'] ], 'IK/FK' )
-
- # Add driver to limit scale constraint influence
- b = org_bones[3]
- drv = pb[b].constraints[-1].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = cls.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
- drv_modifier = cls.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
- # Create toe circle widget
- create_circle_widget(cls.obj, toes, radius=0.4, head_tail=0.5)
-
- bones['ik']['ctrl']['terminal'] += [ toes ]
-
- bones['ik']['ctrl']['terminal'] += [ heel, ctrl ]
-
- return bones
diff --git a/rigify/rigs/pitchipoy/limbs/super_limb.py b/rigify/rigs/pitchipoy/limbs/super_limb.py
deleted file mode 100644
index b1d58ea7..00000000
--- a/rigify/rigs/pitchipoy/limbs/super_limb.py
+++ /dev/null
@@ -1,783 +0,0 @@
-import bpy, re
-from .arm import create_arm
-from .leg import create_leg
-from .paw import create_paw
-from .ui import create_script
-from .limb_utils import *
-from mathutils import Vector
-from ....utils import copy_bone, flip_bone, put_bone, create_cube_widget
-from ....utils import strip_org, make_deformer_name, create_widget
-from ....utils import create_circle_widget, create_sphere_widget
-from ....utils import MetarigError, make_mechanism_name, org
-from ....utils import create_limb_widget, connected_children_names
-from rna_prop_ui import rna_idprop_ui_prop_get
-from ..super_widgets import create_ikarrow_widget
-from math import trunc
-
-class Rig:
- def __init__(self, obj, bone_name, params):
- """ Initialize torso rig and key rig properties """
- self.obj = obj
- self.params = params
-
- if params.limb_type != 'paw':
- self.org_bones = list(
- [bone_name] + connected_children_names(obj, bone_name)
- )[:3] # The basic limb is the first 3 bones
- else:
- self.org_bones = list(
- [bone_name] + connected_children_names(obj, bone_name)
- )[:4] # The basic limb is the first 4 bones for a paw
-
- self.segments = params.segments
- self.bbones = params.bbones
- self.limb_type = params.limb_type
- self.rot_axis = params.rotation_axis
-
- # Assign values to tweak/FK layers props if opted by user
- if params.tweak_extra_layers:
- self.tweak_layers = list(params.tweak_layers)
- else:
- self.tweak_layers = None
-
- if params.fk_extra_layers:
- self.fk_layers = list(params.fk_layers)
- else:
- self.fk_layers = None
-
- def create_parent( self ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- name = get_bone_name( strip_org( org_bones[0] ), 'mch', 'parent' )
-
- mch = copy_bone( self.obj, org_bones[0], name )
- orient_bone( self, eb[mch], 'y' )
- eb[ mch ].length = eb[ org_bones[0] ].length / 4
-
- eb[ mch ].parent = eb[ org_bones[0] ].parent
-
- eb[ mch ].roll = 0.0
-
- # Constraints
- make_constraint( self, mch, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : 'root'
- })
-
- make_constraint( self, mch, {
- 'constraint' : 'COPY_SCALE',
- 'subtarget' : 'root'
- })
-
- # Limb Follow Driver
- pb = self.obj.pose.bones
-
- name = 'FK_limb_follow'
-
- pb[ mch ][ name ] = 0.0
- prop = rna_idprop_ui_prop_get( pb[ mch ], name, create = True )
-
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = name
-
- drv = pb[ mch ].constraints[ 0 ].driver_add("influence").driver
-
- drv.type = 'AVERAGE'
- var = drv.variables.new()
- var.name = name
- var.type = "SINGLE_PROP"
- var.targets[0].id = self.obj
- var.targets[0].data_path = pb[ mch ].path_from_id() + \
- '[' + '"' + name + '"' + ']'
-
- return mch
-
- def create_tweak( self ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- tweaks = {}
- tweaks['ctrl'] = []
- tweaks['mch' ] = []
-
- # Create and parent mch and ctrl tweaks
- for i,org in enumerate(org_bones):
- if i < len(org_bones) - 1:
- # Create segments if specified
- for j in range( self.segments ):
- # MCH
- name = get_bone_name( strip_org(org), 'mch', 'tweak' )
- mch = copy_bone( self.obj, org, name )
-
- # CTRL
- name = get_bone_name( strip_org(org), 'ctrl', 'tweak' )
- ctrl = copy_bone( self.obj, org, name )
-
- eb[ mch ].length /= self.segments
- eb[ ctrl ].length /= self.segments
-
- # If we have more than one segments, place the head of the
- # 2nd and onwards at the correct position
- if j > 0:
- put_bone(self.obj, mch, eb[ tweaks['mch' ][-1] ].tail)
- put_bone(self.obj, ctrl, eb[ tweaks['ctrl'][-1] ].tail)
-
- tweaks['ctrl'] += [ ctrl ]
- tweaks['mch' ] += [ mch ]
-
- # Parenting the tweak ctrls to mchs
- eb[ mch ].parent = eb[ org ]
- eb[ ctrl ].parent = eb[ mch ]
-
- else: # Last limb bone - is not subdivided
- name = get_bone_name( strip_org(org), 'mch', 'tweak' )
- mch = copy_bone( self.obj, org_bones[i-1], name )
- eb[ mch ].length = eb[org].length / 4
- put_bone(
- self.obj,
- mch,
- eb[org_bones[i-1]].tail
- )
-
- ctrl = get_bone_name( strip_org(org), 'ctrl', 'tweak' )
- ctrl = copy_bone( self.obj, org, ctrl )
- eb[ ctrl ].length = eb[org].length / 2
-
- tweaks['mch'] += [ mch ]
- tweaks['ctrl'] += [ ctrl ]
-
- # Parenting the tweak ctrls to mchs
- eb[ mch ].parent = eb[ org ]
- eb[ ctrl ].parent = eb[ mch ]
-
- # Scale to reduce widget size and maintain conventions!
- for mch, ctrl in zip( tweaks['mch'], tweaks['ctrl'] ):
- eb[ mch ].length /= 4
- eb[ ctrl ].length /= 2
-
- # Contraints
- if self.limb_type == 'paw':
-
- for i,b in enumerate( tweaks['mch'] ):
- first = 0
- middle = trunc( len( tweaks['mch'] ) / 3 )
- middle1 = middle + self.segments
- last = len( tweaks['mch'] ) - 1
-
- if i == first or i == middle or i == middle1:
- make_constraint( self, b, {
- 'constraint' : 'COPY_SCALE',
- 'subtarget' : 'root'
- })
- elif i != last:
- targets = []
- factor = 0
- if i < middle:
- dt_target_idx = middle
- targets = [first,middle]
- elif i > middle and i < middle1:
- targets = [middle,middle1]
- factor = self.segments
- dt_target_idx = middle1
- else:
- targets = [middle1,last]
- factor = self.segments * 2
- dt_target_idx = last
-
-
- # Use copy transforms constraints to position each bone
- # exactly in the location respective to its index (between
- # the two edges)
- make_constraint( self, b, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : tweaks['ctrl'][targets[0]],
- })
- make_constraint( self, b, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : tweaks['ctrl'][targets[1]],
- 'influence' : (i - factor) / self.segments
- })
- make_constraint( self, b, {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : tweaks['ctrl'][ dt_target_idx ],
- })
-
- else:
- for i,b in enumerate( tweaks['mch'] ):
- first = 0
- middle = trunc( len( tweaks['mch'] ) / 2 )
- last = len( tweaks['mch'] ) - 1
-
- if i == first or i == middle:
- make_constraint( self, b, {
- 'constraint' : 'COPY_SCALE',
- 'subtarget' : 'root'
- })
- elif i != last:
- targets = []
- dt_target_idx = middle
- factor = 0
- if i < middle:
- targets = [first,middle]
- else:
- targets = [middle,last]
- factor = self.segments
- dt_target_idx = last
-
- # Use copy transforms constraints to position each bone
- # exactly in the location respective to its index (between
- # the two edges)
- make_constraint( self, b, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : tweaks['ctrl'][targets[0]],
- })
- make_constraint( self, b, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : tweaks['ctrl'][targets[1]],
- 'influence' : (i - factor) / self.segments
- })
- make_constraint( self, b, {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : tweaks['ctrl'][ dt_target_idx ],
- })
-
- # Ctrl bones Locks and Widgets
- pb = self.obj.pose.bones
- for t in tweaks['ctrl']:
- pb[t].lock_rotation = True, False, True
- pb[t].lock_scale = False, True, False
-
- create_sphere_widget(self.obj, t, bone_transform_name=None)
-
- if self.tweak_layers:
- pb[t].bone.layers = self.tweak_layers
-
- return tweaks
-
-
- def create_def( self, tweaks ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- def_bones = []
- for i,org in enumerate(org_bones):
- if i < len(org_bones) - 1:
- # Create segments if specified
- for j in range( self.segments ):
- name = get_bone_name( strip_org(org), 'def' )
- def_name = copy_bone( self.obj, org, name )
-
- eb[ def_name ].length /= self.segments
-
- # If we have more than one segments, place the 2nd and
- # onwards on the tail of the previous bone
- if j > 0:
- put_bone(self.obj, def_name, eb[ def_bones[-1] ].tail)
-
- def_bones += [ def_name ]
- else:
- name = get_bone_name( strip_org(org), 'def' )
- def_name = copy_bone( self.obj, org, name )
- def_bones.append( def_name )
-
- # Parent deform bones
- for i,b in enumerate( def_bones ):
- if i > 0: # For all bones but the first (which has no parent)
- eb[b].parent = eb[ def_bones[i-1] ] # to previous
- eb[b].use_connect = True
-
- # Constraint def to tweaks
- for d,t in zip(def_bones, tweaks):
- tidx = tweaks.index(t)
-
- make_constraint( self, d, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : t
- })
-
- if tidx != len(tweaks) - 1:
- make_constraint( self, d, {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : tweaks[ tidx + 1 ],
- })
-
- make_constraint( self, d, {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : tweaks[ tidx + 1 ],
- })
-
- # Create bbone segments
- for bone in def_bones[:-1]:
- self.obj.data.bones[bone].bbone_segments = self.bbones
-
- self.obj.data.bones[ def_bones[0] ].bbone_in = 0.0
- self.obj.data.bones[ def_bones[-2] ].bbone_out = 0.0
- self.obj.data.bones[ def_bones[-1] ].bbone_in = 0.0
- self.obj.data.bones[ def_bones[-1] ].bbone_out = 0.0
-
-
- # Rubber hose drivers
- pb = self.obj.pose.bones
- for i,t in enumerate( tweaks[1:-1] ):
- # Create custom property on tweak bone to control rubber hose
- name = 'rubber_tweak'
-
- if i == trunc( len( tweaks[1:-1] ) / 2 ):
- pb[t][name] = 0.0
- else:
- pb[t][name] = 1.0
-
- prop = rna_idprop_ui_prop_get( pb[t], name, create=True )
-
- prop["min"] = 0.0
- prop["max"] = 2.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = name
-
- for j,d in enumerate(def_bones[:-1]):
- drvs = {}
- if j != 0:
- tidx = j
- drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_in").driver
-
- if j != len( def_bones[:-1] ) - 1:
- tidx = j + 1
- drvs[tidx] = self.obj.data.bones[d].driver_add("bbone_out").driver
-
- for d in drvs:
- drv = drvs[d]
- name = 'rubber_tweak'
- drv.type = 'AVERAGE'
- var = drv.variables.new()
- var.name = name
- var.type = "SINGLE_PROP"
- var.targets[0].id = self.obj
- var.targets[0].data_path = pb[tweaks[d]].path_from_id() + \
- '[' + '"' + name + '"' + ']'
-
- return def_bones
-
-
- def create_ik( self, parent ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- ctrl = get_bone_name( org_bones[0], 'ctrl', 'ik' )
- mch_ik = get_bone_name( org_bones[0], 'mch', 'ik' )
- mch_target = get_bone_name( org_bones[0], 'mch', 'ik_target' )
-
- for o, ik in zip( org_bones, [ ctrl, mch_ik, mch_target ] ):
- bone = copy_bone( self.obj, o, ik )
-
- if org_bones.index(o) == len( org_bones ) - 1:
- eb[ bone ].length /= 4
-
- # Create MCH Stretch
- mch_str = copy_bone(
- self.obj,
- org_bones[0],
- get_bone_name( org_bones[0], 'mch', 'ik_stretch' )
- )
-
- if self.limb_type != 'paw':
- eb[ mch_str ].tail = eb[ org_bones[-1] ].head
- else:
- eb[ mch_str ].tail = eb[ org_bones[-2] ].head
-
- # Parenting
- eb[ ctrl ].parent = eb[ parent ]
- eb[ mch_str ].parent = eb[ parent ]
- eb[ mch_ik ].parent = eb[ ctrl ]
-
-
- make_constraint( self, mch_ik, {
- 'constraint' : 'IK',
- 'subtarget' : mch_target,
- 'chain_count' : 2,
- })
-
- pb = self.obj.pose.bones
- pb[ mch_ik ].ik_stretch = 0.1
- pb[ ctrl ].ik_stretch = 0.1
-
- # IK constraint Rotation locks
- for axis in ['x','y','z']:
- if axis != self.rot_axis:
- setattr( pb[ mch_ik ], 'lock_ik_' + axis, True )
-
- # Locks and Widget
- pb[ ctrl ].lock_rotation = True, False, True
- create_ikarrow_widget( self.obj, ctrl, bone_transform_name=None )
-
- return { 'ctrl' : { 'limb' : ctrl },
- 'mch_ik' : mch_ik,
- 'mch_target' : mch_target,
- 'mch_str' : mch_str
- }
-
-
- def create_fk( self, parent ):
- org_bones = self.org_bones.copy()
-
- if self.limb_type == 'paw': # Paw base chain is one bone longer
- org_bones.pop()
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- ctrls = []
-
- for o in org_bones:
- bone = copy_bone( self.obj, o, get_bone_name( o, 'ctrl', 'fk' ) )
- ctrls.append( bone )
-
- # MCH
- mch = copy_bone(
- self.obj, org_bones[-1], get_bone_name( o, 'mch', 'fk' )
- )
-
- eb[ mch ].length /= 4
-
- # Parenting
- eb[ ctrls[0] ].parent = eb[ parent ]
- eb[ ctrls[1] ].parent = eb[ ctrls[0] ]
- eb[ ctrls[1] ].use_connect = True
- eb[ ctrls[2] ].parent = eb[ mch ]
- eb[ mch ].parent = eb[ ctrls[1] ]
- eb[ mch ].use_connect = True
-
- # Constrain MCH's scale to root
- make_constraint( self, mch, {
- 'constraint' : 'COPY_SCALE',
- 'subtarget' : 'root'
- })
-
- # Locks and widgets
- pb = self.obj.pose.bones
- pb[ ctrls[2] ].lock_location = True, True, True
-
- create_limb_widget( self.obj, ctrls[0] )
- create_limb_widget( self.obj, ctrls[1] )
-
- create_circle_widget(self.obj, ctrls[2], radius=0.4, head_tail=0.0)
-
- for c in ctrls:
- if self.fk_layers:
- pb[c].bone.layers = self.fk_layers
-
- return { 'ctrl' : ctrls, 'mch' : mch }
-
-
- def org_parenting_and_switch( self, org, ik, fk, parent ):
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
- # re-parent ORGs in a connected chain
- for i,o in enumerate(org):
- if i > 0:
- eb[o].parent = eb[ org[i-1] ]
- if i <= len(org)-1:
- eb[o].use_connect = True
-
- bpy.ops.object.mode_set(mode ='OBJECT')
- pb = self.obj.pose.bones
- pb_parent = pb[ parent ]
-
- # Create ik/fk switch property
- pb_parent['IK/FK'] = 0.0
- prop = rna_idprop_ui_prop_get( pb_parent, 'IK/FK', create=True )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = 'IK/FK Switch'
-
- # Constrain org to IK and FK bones
- iks = [ ik['ctrl']['limb'] ]
- iks += [ ik[k] for k in [ 'mch_ik', 'mch_target'] ]
-
- for o, i, f in zip( org, iks, fk ):
- make_constraint( self, o, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : i
- })
- make_constraint( self, o, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : f
- })
-
- # Add driver to relevant constraint
- drv = pb[o].constraints[-1].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop.name
- var.type = "SINGLE_PROP"
- var.targets[0].id = self.obj
- var.targets[0].data_path = \
- pb_parent.path_from_id() + '['+ '"' + prop.name + '"' + ']'
-
-
- def create_terminal( self, limb_type, bones ):
- if limb_type == 'arm':
- return create_arm( self, bones )
- elif limb_type == 'leg':
- return create_leg( self, bones )
- elif limb_type == 'paw':
- return create_paw( self, bones )
-
-
- def generate( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Clear parents for org bones
- for bone in self.org_bones[1:]:
- eb[bone].use_connect = False
- eb[bone].parent = None
-
- bones = {}
-
- # Create mch limb parent
- bones['parent'] = self.create_parent()
- bones['tweak'] = self.create_tweak()
- bones['def'] = self.create_def( bones['tweak']['ctrl'] )
- bones['ik'] = self.create_ik( bones['parent'] )
- bones['fk'] = self.create_fk( bones['parent'] )
-
- self.org_parenting_and_switch(
- self.org_bones, bones['ik'], bones['fk']['ctrl'], bones['parent']
- )
-
- bones = self.create_terminal( self.limb_type, bones )
-
- return [ create_script( bones, self.limb_type ) ]
-
-def add_parameters( params ):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
- """
-
- items = [
- ('arm', 'Arm', ''),
- ('leg', 'Leg', ''),
- ('paw', 'Paw', '')
- ]
- params.limb_type = bpy.props.EnumProperty(
- items = items,
- name = "Limb Type",
- default = 'arm'
- )
-
- items = [
- ('x', 'X', ''),
- ('y', 'Y', ''),
- ('z', 'Z', '')
- ]
- params.rotation_axis = bpy.props.EnumProperty(
- items = items,
- name = "Rotation Axis",
- default = 'x'
- )
-
- params.segments = bpy.props.IntProperty(
- name = 'limb segments',
- default = 2,
- min = 1,
- description = 'Number of segments'
- )
-
- params.bbones = bpy.props.IntProperty(
- name = 'bbone segments',
- default = 10,
- min = 1,
- description = 'Number of segments'
- )
-
- # Setting up extra layers for the FK and tweak
- params.tweak_extra_layers = bpy.props.BoolProperty(
- name = "tweak_extra_layers",
- default = True,
- description = ""
- )
-
- params.tweak_layers = bpy.props.BoolVectorProperty(
- size = 32,
- description = "Layers for the tweak controls to be on",
- default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
-
- # Setting up extra layers for the FK and tweak
- params.fk_extra_layers = bpy.props.BoolProperty(
- name = "fk_extra_layers",
- default = True,
- description = ""
- )
-
- params.fk_layers = bpy.props.BoolVectorProperty(
- size = 32,
- description = "Layers for the FK controls to be on",
- default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters."""
-
- r = layout.row()
- r.prop(params, "limb_type")
-
- r = layout.row()
- r.prop(params, "rotation_axis")
-
- r = layout.row()
- r.prop(params, "segments")
-
- r = layout.row()
- r.prop(params, "bbones")
-
- for layer in [ 'fk', 'tweak' ]:
- r = layout.row()
- r.prop(params, layer + "_extra_layers")
- r.active = params.tweak_extra_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range(8):
- row.prop(params, layer + "_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range(16,24):
- row.prop(params, layer + "_layers", index=i, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range(8,16):
- row.prop(params, layer + "_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range(24,32):
- row.prop(params, layer + "_layers", index=i, toggle=True, text="")
-
-def create_sample(obj):
- # generated by rigify.utils.write_metarig
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
-
- bones = {}
-
- bone = arm.edit_bones.new('upper_arm.L')
- bone.head[:] = -0.0016, 0.0060, -0.0012
- bone.tail[:] = 0.2455, 0.0678, -0.1367
- bone.roll = 2.0724
- bone.use_connect = False
- bones['upper_arm.L'] = bone.name
- bone = arm.edit_bones.new('forearm.L')
- bone.head[:] = 0.2455, 0.0678, -0.1367
- bone.tail[:] = 0.4625, 0.0285, -0.2797
- bone.roll = 2.1535
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['upper_arm.L']]
- bones['forearm.L'] = bone.name
- bone = arm.edit_bones.new('hand.L')
- bone.head[:] = 0.4625, 0.0285, -0.2797
- bone.tail[:] = 0.5265, 0.0205, -0.3273
- bone.roll = 2.2103
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['forearm.L']]
- bones['hand.L'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
- pbone = obj.pose.bones[bones['upper_arm.L']]
- pbone.rigify_type = 'pitchipoy.limbs.super_limb'
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- try:
- pbone.rigify_parameters.separate_ik_layers = True
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.ik_layers = [
- False, False, False, False, False, False, False, False, True, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False
- ]
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.separate_hose_layers = True
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.hose_layers = [
- False, False, False, False, False, False, False, False, False, True,
- False, False, False, False, False, False, False, False, False, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False
- ]
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.tweak_layers = [
- False, False, False, False, False, False, False, False, False, True,
- False, False, False, False, False, False, False, False, False, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False
- ]
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.fk_layers = [
- False, False, False, False, False, False, False, False, True, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False, False, False, False, False, False, False, False, False,
- False, False
- ]
- except AttributeError:
- pass
- pbone = obj.pose.bones[bones['forearm.L']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['hand.L']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
-
- bpy.ops.object.mode_set(mode='EDIT')
- for bone in arm.edit_bones:
- bone.select = False
- bone.select_head = False
- bone.select_tail = False
- for b in bones:
- bone = arm.edit_bones[bones[b]]
- bone.select = True
- bone.select_head = True
- bone.select_tail = True
- arm.edit_bones.active = bone
diff --git a/rigify/rigs/pitchipoy/limbs/super_rear_paw.py b/rigify/rigs/pitchipoy/limbs/super_rear_paw.py
deleted file mode 100644
index c31346c9..00000000
--- 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/pitchipoy/super_torso_turbo.py b/rigify/rigs/pitchipoy/super_torso_turbo.py
deleted file mode 100644
index b6b70085..00000000
--- a/rigify/rigs/pitchipoy/super_torso_turbo.py
+++ /dev/null
@@ -1,911 +0,0 @@
-import bpy
-from mathutils import Vector
-from ...utils import copy_bone, flip_bone, put_bone, org
-from ...utils import strip_org, make_deformer_name, connected_children_names
-from ...utils import create_circle_widget, create_sphere_widget, create_widget
-from ...utils import MetarigError, make_mechanism_name, create_cube_widget
-from rna_prop_ui import rna_idprop_ui_prop_get
-
-script = """
-controls = [%s]
-torso = '%s'
-
-if is_selected( controls ):
- layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
- layout.prop( pose_bones[ torso ], '["%s"]', slider = True )
-"""
-
-class Rig:
-
- def __init__(self, obj, bone_name, params):
- """ Initialize torso rig and key rig properties """
-
- eb = obj.data.edit_bones
-
- self.obj = obj
- self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
- self.params = params
- self.spine_length = sum( [ eb[b].length for b in self.org_bones ] )
-
- # Check if user provided the positions of the neck and pivot
- if params.neck_pos and params.pivot_pos:
- self.neck_pos = params.neck_pos
- self.pivot_pos = params.pivot_pos
- else:
- raise MetarigError(
- "RIGIFY ERROR: please specify neck and pivot bone positions"
- )
-
- # Check if neck is lower than pivot
- if params.neck_pos <= params.pivot_pos:
- raise MetarigError(
- "RIGIFY ERROR: Neck cannot be below or the same as pivot"
- )
-
- # TODO:
- # Limit neck_pos prop to 1 --> num of bones - 1 (last is head)
- # Limit pivot_pos prop to 2 --> num of bones (must leave place for lower torso)
-
- if params.tail_pos:
- self.tail_pos = params.tail_pos
-
- # Assign values to tweak layers props if opted by user
- if params.tweak_extra_layers:
- self.tweak_layers = list(params.tweak_layers)
- else:
- self.tweak_layers = None
-
- # Report error of user created less than the minimum of 4 bones for rig
- if len(self.org_bones) <= 4:
- raise MetarigError(
- "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
- )
-
-
- def build_bone_structure( self ):
- """ Divide meta-rig into lists of bones according to torso rig anatomy:
- Neck --> Upper torso --> Lower torso --> Tail (optional) """
-
- if self.pivot_pos and self.neck_pos:
-
- neck_index = self.neck_pos - 1
- pivot_index = self.pivot_pos - 1
-
- tail_index = 0
- if 'tail_pos' in dir(self):
- tail_index = self.tail_pos - 1
-
- neck_bones = self.org_bones[neck_index::]
- upper_torso_bones = self.org_bones[pivot_index:neck_index]
- lower_torso_bones = self.org_bones[tail_index:pivot_index]
-
- tail_bones = []
- if tail_index:
- tail_bones = self.org_bones[::tail_index+1]
-
- return {
- 'neck' : neck_bones,
- 'upper' : upper_torso_bones,
- 'lower' : lower_torso_bones,
- 'tail' : tail_bones
- }
-
- else:
- return 'ERROR'
-
- def orient_bone( self, eb, axis, scale, reverse = False ):
- v = Vector((0,0,0))
-
- setattr(v,axis,scale)
-
- if reverse:
- tail_vec = v * self.obj.matrix_world
- eb.head[:] = eb.tail
- eb.tail[:] = eb.head + tail_vec
- else:
- tail_vec = v * self.obj.matrix_world
- eb.tail[:] = eb.head + tail_vec
-
-
- def create_pivot( self, pivot ):
- """ Create the pivot control and mechanism bones """
- org_bones = self.org_bones
- pivot_name = org_bones[pivot-1]
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Create torso control bone
- torso_name = 'torso'
- ctrl_name = copy_bone(self.obj, pivot_name, torso_name)
- ctrl_eb = eb[ ctrl_name ]
-
- self.orient_bone( ctrl_eb, 'y', self.spine_length / 2.5 )
-
- # Create mch_pivot
- mch_name = make_mechanism_name( 'pivot' )
- mch_name = copy_bone(self.obj, ctrl_name, mch_name)
- mch_eb = eb[ mch_name ]
-
- mch_eb.length /= 4
-
- # Positioning pivot in a more usable location for animators
- if hasattr(self,'tail_pos') and self.tail_pos > 0:
- pivot_loc = eb[ org_bones[pivot-1]].head
- else:
- pivot_loc = ( eb[ org_bones[0]].head + eb[ org_bones[0]].tail ) / 2
-
- put_bone( self.obj, ctrl_name, pivot_loc )
-
- return {
- 'ctrl' : ctrl_name,
- 'mch' : mch_name
- }
-
-
- def create_deform( self ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- def_bones = []
- for org in org_bones:
- def_name = make_deformer_name( strip_org( org ) )
- def_name = copy_bone( self.obj, org, def_name )
- def_bones.append( def_name )
-
- return def_bones
-
-
- def create_neck( self, neck_bones ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Create neck control
- neck = copy_bone( self.obj, org(neck_bones[0]), 'neck' )
- neck_eb = eb[ neck ]
-
- # Neck spans all neck bones (except head)
- neck_eb.tail[:] = eb[ org(neck_bones[-1]) ].head
-
- # Create head control
- head = copy_bone( self.obj, org(neck_bones[-1]), 'head' )
-
- # MCH bones
- # Neck MCH stretch
- mch_str = copy_bone( self.obj, neck, make_mechanism_name('STR-neck') )
-
- # Neck MCH rotation
- mch_neck = copy_bone(
- self.obj, neck, make_mechanism_name('ROT-neck')
- )
-
- self.orient_bone( eb[mch_neck], 'y', self.spine_length / 10 )
-
- # Head MCH rotation
- mch_head = copy_bone(
- self.obj, head, make_mechanism_name('ROT-head')
- )
-
- self.orient_bone( eb[mch_head], 'y', self.spine_length / 10 )
-
- twk,mch = [],[]
-
- # Intermediary bones
- for b in neck_bones[1:-1]: # All except 1st neck and (last) head
- mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
- eb[mch_name].length /= 4
-
- mch += [ mch_name ]
-
- # Tweak bones
- for b in neck_bones[:-1]: # All except last bone
- twk_name = "tweak_" + b
- twk_name = copy_bone( self.obj, org(b), twk_name )
-
- eb[twk_name].length /= 2
-
- twk += [ twk_name ]
-
- return {
- 'ctrl_neck' : neck,
- 'ctrl' : head,
- 'mch_str' : mch_str,
- 'mch_neck' : mch_neck,
- 'mch_head' : mch_head,
- 'mch' : mch,
- 'tweak' : twk
- }
-
-
- def create_chest( self, chest_bones ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # get total spine length
-
- # Create chest control bone
- chest = copy_bone( self.obj, org( chest_bones[0] ), 'chest' )
- self.orient_bone( eb[chest], 'y', self.spine_length / 3 )
-
- # create chest mch_wgt
- mch_wgt = copy_bone(
- self.obj, org( chest_bones[-1] ),
- make_mechanism_name( 'WGT-chest' )
- )
-
- # Create mch and twk bones
- twk,mch = [],[]
-
- for b in chest_bones:
- mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
- self.orient_bone( eb[mch_name], 'y', self.spine_length / 10 )
-
- twk_name = "tweak_" + b
- twk_name = copy_bone( self.obj, org(b), twk_name )
- eb[twk_name].length /= 2
-
- mch += [ mch_name ]
- twk += [ twk_name ]
-
- return {
- 'ctrl' : chest,
- 'mch' : mch,
- 'tweak' : twk,
- 'mch_wgt' : mch_wgt
- }
-
-
- def create_hips( self, hip_bones ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Create hips control bone
- hips = copy_bone( self.obj, org( hip_bones[-1] ), 'hips' )
- self.orient_bone(
- eb[hips],
- 'y',
- self.spine_length / 4,
- reverse = True
- )
-
- # create hips mch_wgt
- mch_wgt = copy_bone(
- self.obj, org( hip_bones[0] ),
- make_mechanism_name( 'WGT-hips' )
- )
-
- # Create mch and tweak bones
- twk,mch = [],[]
- for b in hip_bones:
- mch_name = copy_bone( self.obj, org(b), make_mechanism_name(b) )
- self.orient_bone(
- eb[mch_name], 'y', self.spine_length / 10, reverse = True
- )
-
- twk_name = "tweak_" + b
- twk_name = copy_bone( self.obj, org( b ), twk_name )
-
- eb[twk_name].length /= 2
-
- mch += [ mch_name ]
- twk += [ twk_name ]
-
- return {
- 'ctrl' : hips,
- 'mch' : mch,
- 'tweak' : twk,
- 'mch_wgt' : mch_wgt
- }
-
-
- def create_tail( self, tail_bones ):
- pass
-
-
- def parent_bones( self, bones ):
- org_bones = self.org_bones
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Parent deform bones
- for i,b in enumerate( bones['def'] ):
- if i > 0: # For all bones but the first (which has no parent)
- eb[b].parent = eb[ bones['def'][i-1] ] # to previous
- eb[b].use_connect = True
-
- # Parent control bones
- # Head control => MCH-rotation_head
- eb[ bones['neck']['ctrl'] ].parent = eb[ bones['neck']['mch_head'] ]
-
- # MCH stretch => neck ctrl
- eb[ bones['neck']['mch_str'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
-
- # Neck control => MCH-rotation_neck
- eb[ bones['neck']['ctrl_neck'] ].parent = eb[ bones['neck']['mch_neck'] ]
-
- # Parent hips and chest controls to torso
- eb[ bones['chest']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
- eb[ bones['hips']['ctrl'] ].parent = eb[ bones['pivot']['ctrl'] ]
-
- # Parent mch bones
- # Neck mch
- eb[ bones['neck']['mch_head'] ].parent = eb[ bones['neck']['ctrl_neck'] ]
-
- parent = eb[ bones['neck']['mch_str'] ]
- for i,b in enumerate([ eb[n] for n in bones['neck']['mch'] ]):
- b.parent = parent
-
- # Chest mch bones and neck mch
- chest_mch = bones['chest']['mch'] + [ bones['neck']['mch_neck'] ]
- for i,b in enumerate(chest_mch):
- if i == 0:
- eb[b].parent = eb[ bones['pivot']['ctrl'] ]
- else:
- eb[b].parent = eb[ chest_mch[i-1] ]
-
- # Hips mch bones
- for i,b in enumerate( bones['hips']['mch'] ):
- if i == len(bones['hips']['mch']) - 1:
- eb[b].parent = eb[ bones['pivot']['ctrl'] ]
- else:
- eb[b].parent = eb[ bones['hips']['mch'][i+1] ]
-
- # mch pivot
- eb[ bones['pivot']['mch'] ].parent = eb[ bones['chest']['mch'][0] ]
-
- # MCH widgets
- eb[ bones['chest']['mch_wgt'] ].parent = eb[ bones['chest']['mch'][-1] ]
- eb[ bones['hips' ]['mch_wgt'] ].parent = eb[ bones['hips' ]['mch'][0 ] ]
-
- # Tweaks
-
- # Neck tweaks
- for i,twk in enumerate( bones['neck']['tweak'] ):
- if i == 0:
- eb[ twk ].parent = eb[ bones['neck']['ctrl_neck'] ]
- else:
- eb[ twk ].parent = eb[ bones['neck']['mch'][i-1] ]
-
- # Chest tweaks
- for twk,mch in zip( bones['chest']['tweak'], bones['chest']['mch'] ):
- if bones['chest']['tweak'].index( twk ) == 0:
- eb[ twk ].parent = eb[ bones['pivot']['mch'] ]
- else:
- eb[ twk ].parent = eb[ mch ]
-
- # Hips tweaks
- for i,twk in enumerate(bones['hips']['tweak']):
- if i == 0:
- eb[twk].parent = eb[ bones['hips']['mch'][i] ]
- else:
- eb[twk].parent = eb[ bones['hips']['mch'][i-1] ]
-
- # Parent orgs to matching tweaks
- tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
- tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
-
- if 'tail' in bones.keys():
- tweaks += bones['tail']['tweak']
-
- for org, twk in zip( org_bones, tweaks ):
- eb[ org ].parent = eb[ twk ]
-
-
- def make_constraint( self, bone, constraint ):
- bpy.ops.object.mode_set(mode = 'OBJECT')
- pb = self.obj.pose.bones
-
- owner_pb = pb[bone]
- const = owner_pb.constraints.new( constraint['constraint'] )
- const.target = self.obj
-
- # filter contraint props to those that actually exist in the currnet
- # type of constraint, then assign values to each
- for p in [ k for k in constraint.keys() if k in dir(const) ]:
- setattr( const, p, constraint[p] )
-
-
- def constrain_bones( self, bones ):
- # MCH bones
-
- # head and neck MCH bones
- for b in [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]:
- self.make_constraint( b, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : bones['pivot']['ctrl'],
- } )
- self.make_constraint( b, {
- 'constraint' : 'COPY_SCALE',
- 'subtarget' : bones['pivot']['ctrl'],
- } )
-
- # Neck MCH Stretch
- self.make_constraint( bones['neck']['mch_str'], {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : bones['neck']['ctrl'],
- })
-
- self.make_constraint( bones['neck']['mch_str'], {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : bones['neck']['ctrl'],
- })
-
- # Intermediary mch bones
- intermediaries = [ bones['neck'], bones['chest'], bones['hips'] ]
-
- if 'tail' in bones.keys():
- intermediaries += bones['tail']
-
- for i,l in enumerate(intermediaries):
- mch = l['mch']
- factor = float( 1 / len( l['tweak'] ) )
-
- for j,b in enumerate(mch):
- if i == 0:
- nfactor = float( (j + 1) / len( mch ) )
- self.make_constraint( b, {
- 'constraint' : 'COPY_ROTATION',
- 'subtarget' : l['ctrl'],
- 'influence' : nfactor
- } )
- else:
- self.make_constraint( b, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : l['ctrl'],
- 'influence' : factor,
- 'owner_space' : 'LOCAL',
- 'target_space' : 'LOCAL'
- } )
-
-
- # MCH pivot
- self.make_constraint( bones['pivot']['mch'], {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : bones['hips']['mch'][-1],
- 'owner_space' : 'LOCAL',
- 'target_space' : 'LOCAL'
- })
-
- # DEF bones
- deform = bones['def']
- tweaks = bones['hips']['tweak'] + bones['chest']['tweak']
- tweaks += bones['neck']['tweak'] + [ bones['neck']['ctrl'] ]
-
- for d,t in zip(deform, tweaks):
- tidx = tweaks.index(t)
-
- self.make_constraint( d, {
- 'constraint' : 'COPY_TRANSFORMS',
- 'subtarget' : t
- })
-
- if tidx != len(tweaks) - 1:
- self.make_constraint( d, {
- 'constraint' : 'DAMPED_TRACK',
- 'subtarget' : tweaks[ tidx + 1 ],
- })
-
- self.make_constraint( d, {
- 'constraint' : 'STRETCH_TO',
- 'subtarget' : tweaks[ tidx + 1 ],
- })
-
- pb = self.obj.pose.bones
-
- for t in tweaks:
- if t != bones['neck']['ctrl']:
- pb[t].rotation_mode = 'ZXY'
-
-
- def create_drivers( self, bones ):
- bpy.ops.object.mode_set(mode ='OBJECT')
- pb = self.obj.pose.bones
-
- # Setting the torso's props
- torso = pb[ bones['pivot']['ctrl'] ]
-
- props = [ "head_follow", "neck_follow" ]
- owners = [ bones['neck']['mch_head'], bones['neck']['mch_neck'] ]
-
- for prop in props:
- if prop == 'neck_follow':
- torso[prop] = 0.5
- else:
- torso[prop] = 0.0
-
- prop = rna_idprop_ui_prop_get( torso, prop, create=True )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = prop
-
- # driving the follow rotation switches for neck and head
- for bone, prop, in zip( owners, props ):
- # Add driver to copy rotation constraint
- drv = pb[ bone ].constraints[ 0 ].driver_add("influence").driver
- drv.type = 'AVERAGE'
-
- var = drv.variables.new()
- var.name = prop
- var.type = "SINGLE_PROP"
- var.targets[0].id = self.obj
- var.targets[0].data_path = \
- torso.path_from_id() + '['+ '"' + prop + '"' + ']'
-
- drv_modifier = self.obj.animation_data.drivers[-1].modifiers[0]
-
- drv_modifier.mode = 'POLYNOMIAL'
- drv_modifier.poly_order = 1
- drv_modifier.coefficients[0] = 1.0
- drv_modifier.coefficients[1] = -1.0
-
-
- def locks_and_widgets( self, bones ):
- bpy.ops.object.mode_set(mode ='OBJECT')
- pb = self.obj.pose.bones
-
- # deform bones bbone segements
- for bone in bones['def'][:-1]:
- self.obj.data.bones[bone].bbone_segments = 8
-
- self.obj.data.bones[ bones['def'][0] ].bbone_in = 0.0
- self.obj.data.bones[ bones['def'][-2] ].bbone_out = 0.0
-
- # Locks
- tweaks = bones['neck']['tweak'] + bones['chest']['tweak']
- tweaks += bones['hips']['tweak']
-
- if 'tail' in bones.keys():
- tweaks += bones['tail']['tweak']
-
- # Tweak bones locks
- for bone in tweaks:
- pb[bone].lock_rotation = True, False, True
- pb[bone].lock_scale = False, True, False
-
- # Widgets
-
- # Assigning a widget to torso bone
- create_cube_widget(
- self.obj,
- bones['pivot']['ctrl'],
- radius = 0.5,
- bone_transform_name = None
- )
-
- # Assigning widgets to control bones
- gen_ctrls = [
- bones['neck']['ctrl_neck'],
- bones['chest']['ctrl'],
- bones['hips']['ctrl']
- ]
-
- if 'tail' in bones.keys():
- gen_ctrls += [ bones['tail']['ctrl'] ]
-
- for bone in gen_ctrls:
- create_circle_widget(
- self.obj,
- bone,
- radius = 1.0,
- head_tail = 0.5,
- with_line = False,
- bone_transform_name = None
- )
-
- # Head widget
- create_circle_widget(
- self.obj,
- bones['neck']['ctrl'],
- radius = 0.75,
- head_tail = 1.0,
- with_line = False,
- bone_transform_name = None
- )
-
- # place widgets on correct bones
- chest_widget_loc = pb[ bones['chest']['mch_wgt'] ]
- pb[ bones['chest']['ctrl'] ].custom_shape_transform = chest_widget_loc
-
- hips_widget_loc = pb[ bones['hips']['mch_wgt'] ]
- if 'tail' in bones.keys():
- hips_widget_loc = bones['def'][self.tail_pos -1]
-
- pb[ bones['hips']['ctrl'] ].custom_shape_transform = hips_widget_loc
-
- # Assigning widgets to tweak bones and layers
- for bone in tweaks:
- create_sphere_widget(self.obj, bone, bone_transform_name=None)
-
- if self.tweak_layers:
- pb[bone].bone.layers = self.tweak_layers
-
-
- def generate( self ):
-
- # Torso Rig Anatomy:
- # Neck: all bones above neck point, last bone is head
- # Upper torso: all bones between pivot and neck start
- # Lower torso: all bones below pivot until tail point
- # Tail: all bones below tail point
-
- bone_chains = self.build_bone_structure()
-
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Clear parents for org bones
- for bone in self.org_bones:
- eb[bone].use_connect = False
- eb[bone].parent = None
-
- if bone_chains != 'ERROR':
-
- # Create lists of bones and strip "ORG" from their names
- neck_bones = [ strip_org(b) for b in bone_chains['neck' ] ]
- upper_torso_bones = [ strip_org(b) for b in bone_chains['upper'] ]
- lower_torso_bones = [ strip_org(b) for b in bone_chains['lower'] ]
- tail_bones = [ strip_org(b) for b in bone_chains['tail' ] ]
-
- bones = {}
-
- bones['def'] = self.create_deform() # Gets org bones from self
- bones['pivot'] = self.create_pivot( self.pivot_pos )
- bones['neck'] = self.create_neck( neck_bones )
- bones['chest'] = self.create_chest( upper_torso_bones )
- bones['hips'] = self.create_hips( lower_torso_bones )
- # TODO: Add create tail
-
- if tail_bones:
- bones['tail'] = self.create_tail( tail_bones )
-
- # TEST
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- self.parent_bones( bones )
- self.constrain_bones( bones )
- self.create_drivers( bones )
- self.locks_and_widgets( bones )
-
-
- controls = [ bones['neck']['ctrl'], bones['neck']['ctrl_neck'] ]
- controls += [ bones['chest']['ctrl'], bones['hips']['ctrl'] ]
- controls += [ bones['pivot']['ctrl'] ]
-
- if 'tail' in bones.keys():
- controls += [ bones['tail']['ctrl'] ]
-
- # Create UI
- controls_string = ", ".join(["'" + x + "'" for x in controls])
- return [script % (
- controls_string,
- bones['pivot']['ctrl'],
- 'head_follow',
- 'neck_follow'
- )]
-
-def add_parameters( params ):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
- """
- params.neck_pos = bpy.props.IntProperty(
- name = 'neck_position',
- default = 6,
- min = 0,
- description = 'Neck start position'
- )
-
- params.pivot_pos = bpy.props.IntProperty(
- name = 'pivot_position',
- default = 3,
- min = 0,
- description = 'Position of the torso control and pivot point'
- )
-
- params.tail_pos = bpy.props.IntProperty(
- name = 'tail_position',
- default = 0,
- min = 0,
- description = 'Where the tail starts (change from 0 to enable)'
- )
-
- # Setting up extra layers for the FK and tweak
- params.tweak_extra_layers = bpy.props.BoolProperty(
- name = "tweak_extra_layers",
- default = True,
- description = ""
- )
-
- params.tweak_layers = bpy.props.BoolVectorProperty(
- size = 32,
- description = "Layers for the tweak controls to be on",
- default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters."""
-
- r = layout.row()
- r.prop(params, "neck_pos")
-
- r = layout.row()
- r.prop(params, "pivot_pos")
-
- r = layout.row()
- r.prop(params, "tail_pos")
-
- r = layout.row()
- r.prop(params, "tweak_extra_layers")
- r.active = params.tweak_extra_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range(8):
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range(16,24):
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range(8,16):
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range(24,32):
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
-def create_sample(obj):
- # generated by rigify.utils.write_metarig
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
-
- bones = {}
-
- bone = arm.edit_bones.new('spine')
- bone.head[:] = 0.0000, 0.0552, 1.0099
- bone.tail[:] = 0.0000, 0.0172, 1.1573
- bone.roll = 0.0000
- bone.use_connect = False
- bones['spine'] = bone.name
-
- bone = arm.edit_bones.new('spine.001')
- bone.head[:] = 0.0000, 0.0172, 1.1573
- bone.tail[:] = 0.0000, 0.0004, 1.2929
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine']]
- bones['spine.001'] = bone.name
-
- bone = arm.edit_bones.new('spine.002')
- bone.head[:] = 0.0000, 0.0004, 1.2929
- bone.tail[:] = 0.0000, 0.0059, 1.4657
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine.001']]
- bones['spine.002'] = bone.name
-
- bone = arm.edit_bones.new('spine.003')
- bone.head[:] = 0.0000, 0.0059, 1.4657
- bone.tail[:] = 0.0000, 0.0114, 1.6582
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine.002']]
- bones['spine.003'] = bone.name
-
- bone = arm.edit_bones.new('spine.004')
- bone.head[:] = 0.0000, 0.0114, 1.6582
- bone.tail[:] = 0.0000, -0.0067, 1.7197
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine.003']]
- bones['spine.004'] = bone.name
-
- bone = arm.edit_bones.new('spine.005')
- bone.head[:] = 0.0000, -0.0067, 1.7197
- bone.tail[:] = 0.0000, -0.0247, 1.7813
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine.004']]
- bones['spine.005'] = bone.name
-
- bone = arm.edit_bones.new('spine.006')
- bone.head[:] = 0.0000, -0.0247, 1.7813
- bone.tail[:] = 0.0000, -0.0247, 1.9796
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine.005']]
- bones['spine.006'] = bone.name
-
-
- bpy.ops.object.mode_set(mode='OBJECT')
- pbone = obj.pose.bones[bones['spine']]
- pbone.rigify_type = 'pitchipoy.super_torso_turbo'
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- try:
- pbone.rigify_parameters.chain_bone_controls = "1, 2, 3"
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.neck_pos = 5
- except AttributeError:
- pass
- try:
- pbone.rigify_parameters.tweak_layers = [False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
- except AttributeError:
- pass
- pbone = obj.pose.bones[bones['spine.001']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['spine.002']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['spine.003']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['spine.004']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['spine.005']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- pbone = obj.pose.bones[bones['spine.006']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
-
- bpy.ops.object.mode_set(mode='EDIT')
- for bone in arm.edit_bones:
- bone.select = False
- bone.select_head = False
- bone.select_tail = False
- for b in bones:
- bone = arm.edit_bones[bones[b]]
- bone.select = True
- bone.select_head = True
- bone.select_tail = True
- arm.edit_bones.active = bone
diff --git a/rigify/rigs/pitchipoy/tentacle.py b/rigify/rigs/pitchipoy/tentacle.py
deleted file mode 100644
index 0d24be16..00000000
--- a/rigify/rigs/pitchipoy/tentacle.py
+++ /dev/null
@@ -1,509 +0,0 @@
-import bpy
-from ...utils import copy_bone
-from ...utils import strip_org, make_deformer_name, connected_children_names
-from ...utils import make_mechanism_name, put_bone, create_sphere_widget
-from ...utils import create_widget, create_circle_widget
-from ...utils import MetarigError
-from rna_prop_ui import rna_idprop_ui_prop_get
-
-script = """
-controls = [%s]
-master_name = '%s'
-
-if is_selected( controls ):
- layout.prop( pose_bones[ master_name ], '["%s"]', slider = True )
- layout.prop( pose_bones[ master_name ], '["%s"]', slider = True )
-"""
-
-class Rig:
-
- def __init__(self, obj, bone_name, params):
- self.obj = obj
- self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
- self.params = params
-
- if params.tweak_extra_layers:
- self.tweak_layers = list( params.tweak_layers )
- else:
- self.tweak_layers = None
-
- if len(self.org_bones) <= 1:
- raise MetarigError(
- "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
- )
-
-
- def make_mch( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- org_bones = self.org_bones
- mch_parent = self.obj.data.bones[ org_bones[0] ].parent
-
- mch_parent_name = mch_parent.name # Storing the mch parent's name
-
- if not mch_parent:
- mch_parent = self.obj.data.edit_bones[ org_bones[0] ]
- mch_bone = copy_bone(
- self.obj,
- mch_parent_name,
- make_mechanism_name( strip_org( org_bones[0] ) )
- )
- else:
- mch_bone = copy_bone(
- self.obj,
- mch_parent_name,
- make_mechanism_name( strip_org( org_bones[0] ) )
- )
-
- put_bone( self.obj, mch_bone, eb[ mch_parent_name ].tail )
-
- eb[ mch_bone ].length /= 4 # reduce length to fourth of original
-
- return mch_bone
-
-
- def make_master( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
-
- org_bones = self.org_bones
-
- master_bone = copy_bone(
- self.obj,
- org_bones[0],
- "master_" + strip_org( org_bones[0] )
- )
-
- # Make widgets
- bpy.ops.object.mode_set(mode ='OBJECT')
-
- create_square_widget( self.obj, master_bone )
-
- return master_bone
-
-
- def make_controls( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
-
- org_bones = self.org_bones
-
- ctrl_chain = []
- for i in range( len( org_bones ) ):
- name = org_bones[i]
-
- ctrl_bone = copy_bone(
- self.obj,
- name,
- strip_org(name)
- )
-
- ctrl_chain.append( ctrl_bone )
-
- # Make widgets
- bpy.ops.object.mode_set(mode ='OBJECT')
-
- for ctrl in ctrl_chain:
- create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5)
-
- return ctrl_chain
-
-
- def make_tweaks( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
- org_bones = self.org_bones
-
- tweak_chain = []
- for i in range( len( org_bones ) + 1 ):
- if i == len( org_bones ):
- # Make final tweak at the tip of the tentacle
- name = org_bones[i-1]
- else:
- name = org_bones[i]
-
- tweak_bone = copy_bone(
- self.obj,
- name,
- "tweak_" + strip_org(name)
- )
-
- tweak_e = eb[ tweak_bone ]
-
- tweak_e.length /= 2 # Set size to half
-
- if i == len( org_bones ):
- # Position final tweak at the tip
- put_bone( self.obj, tweak_bone, eb[ org_bones[-1]].tail )
-
- tweak_chain.append( tweak_bone )
-
- # Make widgets
- bpy.ops.object.mode_set(mode = 'OBJECT')
-
- for tweak in tweak_chain:
- create_sphere_widget( self.obj, tweak )
-
- tweak_pb = self.obj.pose.bones[ tweak ]
-
- # Set locks
- if tweak_chain.index( tweak ) != len( tweak_chain ) - 1:
- tweak_pb.lock_rotation = (True, False, True)
- tweak_pb.lock_scale = (False, True, False)
- else:
- tweak_pb.lock_rotation_w = True
- tweak_pb.lock_rotation = (True, True, True)
- tweak_pb.lock_scale = (True, True, True)
-
- # Set up tweak bone layers
- if self.tweak_layers:
- tweak_pb.bone.layers = self.tweak_layers
-
- return tweak_chain
-
-
- def make_deform( self ):
- bpy.ops.object.mode_set(mode ='EDIT')
-
- org_bones = self.org_bones
-
- def_chain = []
- for i in range( len( org_bones ) ):
- name = org_bones[i]
-
- def_bone = copy_bone(
- self.obj,
- name,
- make_deformer_name(strip_org(name))
- )
-
- def_chain.append( def_bone )
-
- return def_chain
-
-
- def parent_bones( self, all_bones ):
- bpy.ops.object.mode_set(mode ='EDIT')
-
- org_bones = self.org_bones
- eb = self.obj.data.edit_bones
-
- """ for category in all_bones:
- if isinstance( all_bones[category], list ):
- for bone in all_bones[category]:
- print( "Bone: " + bone )
- eb[bone].parent = None
- else:
- eb[ all_bones[category] ].parent = None
- """
-
- # mch bone remains parentless and will be parented to root by rigify
-
- # Parent master bone
- # eb[ all_bones['master'] ].parent = eb[ all_bones['mch'] ]
-
- # Parent control bones
- # ctrls_n_parent = [ all_bones['master'] ] + all_bones['control']
-
- for bone in ctrls_n_parent[1:]:
- previous_index = ctrls_n_parent.index( bone ) - 1
- eb[ bone ].parent = eb[ ctrls_n_parent[previous_index] ]
-
- # Parent tweak bones
- tweaks = all_bones['tweak']
- for tweak in all_bones['tweak']:
- parent = ''
- if tweaks.index( tweak ) == len( tweaks ) - 1:
- parent = all_bones['control'][ -1 ]
- else:
- parent = all_bones['control'][ tweaks.index( tweak ) ]
-
- eb[ tweak ].parent = eb[ parent ]
-
- # Parent deform bones
- for bone in all_bones['deform'][1:]:
- previous_index = all_bones['deform'].index( bone ) - 1
-
- eb[ bone ].parent = eb[ all_bones['deform'][previous_index] ]
- eb[ bone ].use_connect = True
-
- # Parent org bones ( to tweaks by default, or to the controls )
- for org, tweak in zip( org_bones, all_bones['tweak'] ):
- eb[ org ].parent = eb[ tweak ]
-
-
- def make_constraints( self, all_bones ):
- bpy.ops.object.mode_set(mode ='OBJECT')
-
- org_bones = self.org_bones
- pb = self.obj.pose.bones
-
- ## MCH bone constraints
- if pb[ org_bones[0] ].parent:
- mch_pb = pb[ all_bones['mch'] ]
-
- con = mch_pb.constraints.new('COPY_LOCATION')
- con.target = self.obj
- con.subtarget = pb[ org_bones[0] ].parent.name
- con.head_tail = 1.0
-
- con = mch_pb.constraints.new('COPY_ROTATION')
- con.target = self.obj
- con.subtarget = pb[ org_bones[0] ].parent.name
-
- con = mch_pb.constraints.new('COPY_SCALE')
- con.target = self.obj
- con.subtarget = pb[ org_bones[0] ].parent.name
-
- """
- # Setting the MCH prop
- master_pb = pb[ all_bones['master'] ]
- prop_name_r = "rotation_follow"
- prop_name_s = "scale_follow"
-
- prop_names = [ prop_name_r, prop_name_s ]
-
- for prop_name in prop_names:
- master_pb[prop_name] = 1.0
-
- prop = rna_idprop_ui_prop_get( master_pb, prop_name )
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
- prop["description"] = prop_name
-
- # driving the MCH follow rotation switch
-
- drv = mch_pb.constraints[
- prop_names.index(prop_name) +1
- ].driver_add("influence").driver
-
- drv.type='SUM'
-
- var = drv.variables.new()
- var.name = prop_name
- var.type = "SINGLE_PROP"
- var.targets[0].id = self.obj
- var.targets[0].data_path = \
- master_pb.path_from_id() + '['+ '"' + prop_name + '"' + ']'
-
- """
-
- ## Deform bones' constraints
- ctrls = all_bones['control']
- tweaks = all_bones['tweak' ]
- deforms = all_bones['deform' ]
-
- for deform, tweak, ctrl in zip( deforms, tweaks, ctrls ):
- con = pb[deform].constraints.new('COPY_TRANSFORMS')
- con.target = self.obj
- con.subtarget = tweak
-
- con = pb[deform].constraints.new('DAMPED_TRACK')
- con.target = self.obj
- con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
-
- con = pb[deform].constraints.new('STRETCH_TO')
- con.target = self.obj
- con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
-
- ## Control bones' constraints
- if self.params.make_rotations:
- if ctrl != ctrls[0]:
- con = pb[ctrl].constraints.new('COPY_ROTATION')
- con.target = self.obj
- con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ]
- con.use_offset = True
- con.target_space = 'LOCAL'
- con.owner_space = 'LOCAL'
-
-
- def generate(self):
- bpy.ops.object.mode_set(mode ='EDIT')
- eb = self.obj.data.edit_bones
-
- # Clear all initial parenting
- for bone in self.org_bones:
- # eb[ bone ].parent = None
- eb[ bone ].use_connect = False
-
- # Creating all bones
- mch = self.make_mch()
- # master = self.make_master()
- ctrl_chain = self.make_controls()
- tweak_chain = self.make_tweaks()
- def_chain = self.make_deform()
-
- all_bones = {
- 'mch' : mch,
- # 'master' : master,
- 'control' : ctrl_chain,
- 'tweak' : tweak_chain,
- 'deform' : def_chain
- }
-
- self.make_constraints( all_bones )
- self.parent_bones( all_bones )
-
- """
- # Create UI
- all_controls = all_bones['control'] + all_bones['tweak'] # + [ all_bones['master'] ]
- controls_string = ", ".join(["'" + x + "'" for x in all_controls])
- return [script % (
- controls_string,
- 'rotation_follow',
- 'scale_follow'
- )]
- """
-
-def add_parameters(params):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
- """
- params.make_rotations = bpy.props.BoolProperty(
- name = "Rotations",
- default = True,
- description = "Make bones follow parent rotation"
- )
-
- # Setting up extra tweak layers
- params.tweak_extra_layers = bpy.props.BoolProperty(
- name = "tweak_extra_layers",
- default = True,
- description = ""
- )
-
- params.tweak_layers = bpy.props.BoolVectorProperty(
- size = 32,
- description = "Layers for the tweak controls to be on",
- default = tuple( [ i == 1 for i in range(0, 32) ] )
- )
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters.
- """
-
- r = layout.row()
- r.prop(params, "make_rotations")
-
- r = layout.row()
- r.prop(params, "tweak_extra_layers")
- r.active = params.tweak_extra_layers
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range( 8 ): # Layers 0-7
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range( 16, 24 ): # Layers 16-23
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- col = r.column(align=True)
- row = col.row(align=True)
-
- for i in range( 8, 16 ): # Layers 8-15
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
- row = col.row(align=True)
-
- for i in range( 24, 32 ): # Layers 24-31
- row.prop(params, "tweak_layers", index=i, toggle=True, text="")
-
-
-def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None):
- obj = create_widget(rig, bone_name, bone_transform_name)
- if obj is not None:
- verts = [
- ( 0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ),
- ( -0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ),
- ( 0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ),
- ( -0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ),
- ]
-
- edges = [(0, 1), (2, 3), (0, 2), (3, 1) ]
- faces = []
-
- mesh = obj.data
- mesh.from_pydata(verts, edges, faces)
- mesh.update()
- mesh.update()
- return obj
- else:
- return None
-
-def create_sample(obj):
- # generated by rigify.utils.write_metarig
-
- bpy.ops.object.mode_set(mode='EDIT')
- arm = obj.data
- bones = {}
-
- bone = arm.edit_bones.new('tentacle')
- bone.head[:] = 0.0000, 0.0000, 0.0000
- bone.tail[:] = 0.0000, 0.0000, 1.0000
- bone.roll = 0.0000
- bone.use_connect = False
-
- bones['tentacle'] = bone.name
-
- bone = arm.edit_bones.new('tentacle.001')
- bone.head[:] = 0.0000, 0.0000, 1.0000
- bone.tail[:] = 0.0000, 0.0000, 2.0000
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['tentacle']]
-
- bones['tentacle.001'] = bone.name
-
- bone = arm.edit_bones.new('tentacle.002')
- bone.head[:] = 0.0000, 0.0000, 2.0000
- bone.tail[:] = 0.0000, 0.0000, 3.0000
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['tentacle.001']]
- bones['tentacle.002'] = bone.name
-
- bpy.ops.object.mode_set(mode='OBJECT')
-
- pbone = obj.pose.bones[bones['tentacle']]
- pbone.rigify_type = 'tentacle'
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
-
- pbone.rotation_mode = 'QUATERNION'
-
- pbone = obj.pose.bones[bones['tentacle.001']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
-
- pbone.rotation_mode = 'QUATERNION'
-
- pbone = obj.pose.bones[bones['tentacle.002']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, False, False)
- pbone.lock_rotation = (False, False, False)
- pbone.lock_rotation_w = False
- pbone.lock_scale = (False, False, False)
- pbone.rotation_mode = 'QUATERNION'
- bpy.ops.object.mode_set(mode='EDIT')
-
- for bone in arm.edit_bones:
- bone.select = False
- bone.select_head = False
- bone.select_tail = False
-
- for b in bones:
- bone = arm.edit_bones[bones[b]]
- bone.select = True
- bone.select_head = True
- bone.select_tail = True
- arm.edit_bones.active = bone
diff --git a/rigify/rigs/spine.py b/rigify/rigs/spine.py
deleted file mode 100644
index 680a4ceb..00000000
--- a/rigify/rigs/spine.py
+++ /dev/null
@@ -1,567 +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>
-
-""" TODO:
- - Add parameters for bone transform alphas.
- - Add IK spine controls
-"""
-
-from math import floor
-
-import bpy
-from mathutils import Vector
-from rna_prop_ui import rna_idprop_ui_prop_get
-
-from ..utils import MetarigError
-from ..utils import copy_bone, new_bone, flip_bone, put_bone
-from ..utils import connected_children_names
-from ..utils import strip_org, make_mechanism_name, make_deformer_name
-from ..utils import create_circle_widget, create_cube_widget
-
-script = """
-main = "%s"
-spine = [%s]
-if is_selected([main]+ spine):
- layout.prop(pose_bones[main], '["pivot_slide"]', text="Pivot Slide (" + main + ")", slider=True)
-
-for name in spine[1:-1]:
- if is_selected(name):
- layout.prop(pose_bones[name], '["auto_rotate"]', text="Auto Rotate (" + name + ")", slider=True)
-"""
-
-
-class Rig:
- """ A "spine" rig. It turns a chain of bones into a rig with two controls:
- One for the hips, and one for the rib cage.
-
- """
- 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
-
- # Collect control bone indices
- self.control_indices = [0, len(self.org_bones) - 1]
- temp = self.params.chain_bone_controls.split(",")
- for i in temp:
- try:
- j = int(i) - 1
- except ValueError:
- pass
- else:
- if (j > 0) and (j < len(self.org_bones)) and (j not in self.control_indices):
- self.control_indices += [j]
- self.control_indices.sort()
-
- self.pivot_rest = self.params.rest_pivot_slide
- # Clamp pivot_rest to within the middle bones of the spine
- self.pivot_rest = max(self.pivot_rest, 1.0 / len(self.org_bones))
- self.pivot_rest = min(self.pivot_rest, 1.0 - (1.0 / len(self.org_bones)))
-
- 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 gen_deform(self):
- """ Generate the deformation rig.
-
- """
- for name in self.org_bones:
- bpy.ops.object.mode_set(mode='EDIT')
- eb = self.obj.data.edit_bones
-
- # Create deform bone
- bone_e = eb[copy_bone(self.obj, name)]
-
- # Change its name
- bone_e.name = make_deformer_name(strip_org(name))
- bone_name = bone_e.name
-
- # Leave edit mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Get the pose bone
- bone = self.obj.pose.bones[bone_name]
-
- # Constrain to the original bone
- con = bone.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name
-
- def gen_control(self):
- """ Generate the control rig.
-
- """
- bpy.ops.object.mode_set(mode='EDIT')
- eb = self.obj.data.edit_bones
- #-------------------------
- # Get rest slide position
- a = self.pivot_rest * len(self.org_bones)
- i = floor(a)
- a -= i
- if i == len(self.org_bones):
- i -= 1
- a = 1.0
-
- pivot_rest_pos = eb[self.org_bones[i]].head.copy()
- pivot_rest_pos += eb[self.org_bones[i]].vector * a
-
- #----------------------
- # Create controls
-
- # Create control bones
- controls = []
- for i in self.control_indices:
- name = copy_bone(self.obj, self.org_bones[i], strip_org(self.org_bones[i]))
- controls += [name]
-
- # Create control parents
- control_parents = []
- for i in self.control_indices[1:-1]:
- name = new_bone(self.obj, make_mechanism_name("par_" + strip_org(self.org_bones[i])))
- control_parents += [name]
-
- # Create sub-control bones
- subcontrols = []
- for i in self.control_indices:
- name = new_bone(self.obj, make_mechanism_name("sub_" + strip_org(self.org_bones[i])))
- subcontrols += [name]
-
- # Create main control bone
- main_control = new_bone(self.obj, self.params.spine_main_control_name)
-
- eb = self.obj.data.edit_bones
-
- # Parent the main control
- eb[main_control].use_connect = False
- eb[main_control].parent = eb[self.org_bones[0]].parent
-
- # Parent the controls and sub-controls
- for name, subname in zip(controls, subcontrols):
- eb[name].use_connect = False
- eb[name].parent = eb[main_control]
- eb[subname].use_connect = False
- eb[subname].parent = eb[name]
-
- # Parent the control parents
- for name, par_name in zip(controls[1:-1], control_parents):
- eb[par_name].use_connect = False
- eb[par_name].parent = eb[main_control]
- eb[name].parent = eb[par_name]
-
- # Position the main bone
- put_bone(self.obj, main_control, pivot_rest_pos)
- eb[main_control].length = sum([eb[b].length for b in self.org_bones]) / 2
-
- # Position the controls and sub-controls
- for name, subname in zip(controls, subcontrols):
- put_bone(self.obj, name, pivot_rest_pos)
- put_bone(self.obj, subname, pivot_rest_pos)
- eb[subname].length = eb[name].length / 3
-
- # Position the control parents
- for name, par_name in zip(controls[1:-1], control_parents):
- put_bone(self.obj, par_name, pivot_rest_pos)
- eb[par_name].length = eb[name].length / 2
-
- #-----------------------------------------
- # Control bone constraints and properties
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- # Lock control locations
- for name in controls:
- bone = pb[name]
- bone.lock_location = True, True, True
-
- # Main control doesn't use local location
- pb[main_control].bone.use_local_location = False
-
- # Intermediate controls follow hips and spine
- for name, par_name, i in zip(controls[1:-1], control_parents, self.control_indices[1:-1]):
- bone = pb[par_name]
-
- # Custom bend_alpha property
- prop = rna_idprop_ui_prop_get(pb[name], "bend_alpha", create=True)
- pb[name]["bend_alpha"] = i / (len(self.org_bones) - 1) # set bend alpha
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- # Custom auto_rotate
- prop = rna_idprop_ui_prop_get(pb[name], "auto_rotate", create=True)
- pb[name]["auto_rotate"] = 1.0
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- # Constraints
- con1 = bone.constraints.new('COPY_TRANSFORMS')
- con1.name = "copy_transforms"
- con1.target = self.obj
- con1.subtarget = subcontrols[0]
-
- con2 = bone.constraints.new('COPY_TRANSFORMS')
- con2.name = "copy_transforms"
- con2.target = self.obj
- con2.subtarget = subcontrols[-1]
-
- # Drivers
- fcurve = con1.driver_add("influence")
- driver = fcurve.driver
- driver.type = 'AVERAGE'
- var = driver.variables.new()
- var.name = "auto"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = pb[name].path_from_id() + '["auto_rotate"]'
-
- fcurve = con2.driver_add("influence")
- driver = fcurve.driver
- driver.type = 'SCRIPTED'
- driver.expression = "alpha * auto"
- var = driver.variables.new()
- var.name = "alpha"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = pb[name].path_from_id() + '["bend_alpha"]'
- var = driver.variables.new()
- var.name = "auto"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = pb[name].path_from_id() + '["auto_rotate"]'
-
- #-------------------------
- # Create flex spine chain
- bpy.ops.object.mode_set(mode='EDIT')
- flex_bones = []
- flex_subs = []
- prev_bone = None
- for b in self.org_bones:
- # Create bones
- bone = copy_bone(self.obj, b, make_mechanism_name(strip_org(b) + ".flex"))
- sub = new_bone(self.obj, make_mechanism_name(strip_org(b) + ".flex_s"))
- flex_bones += [bone]
- flex_subs += [sub]
-
- eb = self.obj.data.edit_bones
- bone_e = eb[bone]
- sub_e = eb[sub]
-
- # Parenting
- bone_e.use_connect = False
- sub_e.use_connect = False
- if prev_bone is None:
- sub_e.parent = eb[controls[0]]
- else:
- sub_e.parent = eb[prev_bone]
- bone_e.parent = sub_e
-
- # Position
- put_bone(self.obj, sub, bone_e.head)
- sub_e.length = bone_e.length / 4
- if prev_bone is not None:
- sub_e.use_connect = True
-
- prev_bone = bone
-
- #----------------------------
- # Create reverse spine chain
-
- # Create bones/parenting/positioning
- bpy.ops.object.mode_set(mode='EDIT')
- rev_bones = []
- prev_bone = None
- for b in zip(flex_bones, self.org_bones):
- # Create bones
- bone = copy_bone(self.obj, b[1], make_mechanism_name(strip_org(b[1]) + ".reverse"))
- rev_bones += [bone]
- eb = self.obj.data.edit_bones
- bone_e = eb[bone]
-
- # Parenting
- bone_e.use_connect = False
- bone_e.parent = eb[b[0]]
-
- # Position
- flip_bone(self.obj, bone)
- bone_e.tail = Vector(eb[b[0]].head)
- #bone_e.head = Vector(eb[b[0]].tail)
- if prev_bone is None:
- put_bone(self.obj, bone, pivot_rest_pos)
- else:
- put_bone(self.obj, bone, eb[prev_bone].tail)
-
- prev_bone = bone
-
- # Constraints
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
- prev_bone = None
- for bone in rev_bones:
- bone_p = pb[bone]
-
- con = bone_p.constraints.new('COPY_LOCATION')
- con.name = "copy_location"
- con.target = self.obj
- if prev_bone is None:
- con.subtarget = main_control
- else:
- con.subtarget = prev_bone
- con.head_tail = 1.0
- prev_bone = bone
-
- #----------------------------------------
- # Constrain original bones to flex spine
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- for obone, fbone in zip(self.org_bones, flex_bones):
- con = pb[obone].constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = fbone
-
- #---------------------------
- # Create pivot slide system
- pb = self.obj.pose.bones
- bone_p = pb[self.org_bones[0]]
- main_control_p = pb[main_control]
-
- # Custom pivot_slide property
- prop = rna_idprop_ui_prop_get(main_control_p, "pivot_slide", create=True)
- main_control_p["pivot_slide"] = self.pivot_rest
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 1.0 / len(self.org_bones)
- prop["soft_max"] = 1.0 - (1.0 / len(self.org_bones))
-
- # Anchor constraints
- con = bone_p.constraints.new('COPY_LOCATION')
- con.name = "copy_location"
- con.target = self.obj
- con.subtarget = rev_bones[0]
-
- # Slide constraints
- i = 1
- tot = len(rev_bones)
- for rb in rev_bones:
- con = bone_p.constraints.new('COPY_LOCATION')
- con.name = "slide." + str(i)
- con.target = self.obj
- con.subtarget = rb
- con.head_tail = 1.0
-
- # Driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "slide"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = main_control_p.path_from_id() + '["pivot_slide"]'
- mod = fcurve.modifiers[0]
- mod.poly_order = 1
- mod.coefficients[0] = 1 - i
- mod.coefficients[1] = tot
-
- i += 1
-
- #----------------------------------
- # Constrain flex spine to controls
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- # Constrain the bones that correspond exactly to the controls
- for i, name in zip(self.control_indices, subcontrols):
- con = pb[flex_subs[i]].constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name
-
- # Constrain the bones in-between the controls
- for i, j, name1, name2 in zip(self.control_indices, self.control_indices[1:], subcontrols, subcontrols[1:]):
- if (i + 1) < j:
- for n in range(i + 1, j):
- bone = pb[flex_subs[n]]
- # Custom bend_alpha property
- prop = rna_idprop_ui_prop_get(bone, "bend_alpha", create=True)
- bone["bend_alpha"] = (n - i) / (j - i) # set bend alpha
- prop["min"] = 0.0
- prop["max"] = 1.0
- prop["soft_min"] = 0.0
- prop["soft_max"] = 1.0
-
- con = bone.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name1
-
- con = bone.constraints.new('COPY_TRANSFORMS')
- con.name = "copy_transforms"
- con.target = self.obj
- con.subtarget = name2
-
- # Driver
- fcurve = con.driver_add("influence")
- driver = fcurve.driver
- var = driver.variables.new()
- driver.type = 'AVERAGE'
- var.name = "alpha"
- var.targets[0].id_type = 'OBJECT'
- var.targets[0].id = self.obj
- var.targets[0].data_path = bone.path_from_id() + '["bend_alpha"]'
-
- #-------------
- # Final stuff
- bpy.ops.object.mode_set(mode='OBJECT')
- pb = self.obj.pose.bones
-
- # Control appearance
- # Main
- create_cube_widget(self.obj, main_control)
-
- # Spines
- for name, i in zip(controls[1:-1], self.control_indices[1:-1]):
- pb[name].custom_shape_transform = pb[self.org_bones[i]]
- # Create control widgets
- create_circle_widget(self.obj, name, radius=1.0, head_tail=0.5, with_line=True, bone_transform_name=self.org_bones[i])
-
- # Hips
- pb[controls[0]].custom_shape_transform = pb[self.org_bones[0]]
- # Create control widgets
- create_circle_widget(self.obj, controls[0], radius=1.0, head_tail=0.5, with_line=True, bone_transform_name=self.org_bones[0])
-
- # Ribs
- pb[controls[-1]].custom_shape_transform = pb[self.org_bones[-1]]
- # Create control widgets
- create_circle_widget(self.obj, controls[-1], radius=1.0, head_tail=0.5, with_line=True, bone_transform_name=self.org_bones[-1])
-
- # Layers
- pb[main_control].bone.layers = pb[self.org_bones[0]].bone.layers
-
- return [main_control] + controls
-
- 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.gen_deform()
- controls = self.gen_control()
-
- controls_string = ", ".join(["'" + x + "'" for x in controls[1:]])
- return [script % (controls[0], controls_string)]
-
-
-def add_parameters(params):
- """ Add the parameters of this rig type to the
- RigifyParameters PropertyGroup
- """
- params.spine_main_control_name = bpy.props.StringProperty(name="Main control name", default="torso", description="Name that the main control bone should be given")
- params.rest_pivot_slide = bpy.props.FloatProperty(name="Rest Pivot Slide", default=0.0, min=0.0, max=1.0, soft_min=0.0, soft_max=1.0, description="The pivot slide value in the rest pose")
- params.chain_bone_controls = bpy.props.StringProperty(name="Control bone list", default="", description="Define which bones have controls")
-
-
-def parameters_ui(layout, params):
- """ Create the ui for the rig parameters.
- """
- r = layout.row()
- r.prop(params, "spine_main_control_name")
-
- r = layout.row()
- r.prop(params, "rest_pivot_slide", slider=True)
-
- r = layout.row()
- r.prop(params, "chain_bone_controls")
-
-
-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('hips')
- bone.head[:] = 0.0000, 0.0000, 0.0000
- bone.tail[:] = -0.0000, -0.0590, 0.2804
- bone.roll = -0.0000
- bone.use_connect = False
- bones['hips'] = bone.name
- bone = arm.edit_bones.new('spine')
- bone.head[:] = -0.0000, -0.0590, 0.2804
- bone.tail[:] = 0.0000, 0.0291, 0.5324
- bone.roll = 0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['hips']]
- bones['spine'] = bone.name
- bone = arm.edit_bones.new('ribs')
- bone.head[:] = 0.0000, 0.0291, 0.5324
- bone.tail[:] = -0.0000, 0.0000, 1.0000
- bone.roll = -0.0000
- bone.use_connect = True
- bone.parent = arm.edit_bones[bones['spine']]
- bones['ribs'] = 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 = 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 = obj.pose.bones[bones['ribs']]
- pbone.rigify_type = ''
- pbone.lock_location = (False, 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['hips']]
- pbone['rigify_type'] = 'spine'
- pbone.rigify_parameters.chain_bone_controls = "1, 2, 3"
-
- 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/spines/__init__.py b/rigify/rigs/spines/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rigify/rigs/spines/__init__.py
diff --git a/rigify/rigs/spines/super_spine.py b/rigify/rigs/spines/super_spine.py
new file mode 100644
index 00000000..832a506a
--- /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/pitchipoy/super_widgets.py b/rigify/rigs/widgets.py
index 8930ba91..0d3e9305 100644
--- a/rigify/rigs/pitchipoy/super_widgets.py
+++ b/rigify/rigs/widgets.py
@@ -1,9 +1,9 @@
import bpy
import importlib
import importlib
-from ...utils import create_widget
+from ..utils import create_widget
-WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
+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
@@ -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,14 +66,14 @@ 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()
@@ -81,6 +81,7 @@ def create_teeth_widget(rig, bone_name, size=1.0, bone_transform_name=None):
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:
@@ -129,10 +130,11 @@ def create_hand_widget(rig, bone_name, size=1.0, bone_transform_name=None):
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:
+ 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 = []
@@ -147,13 +149,14 @@ def create_foot_widget(rig, bone_name, size=1.0, bone_transform_name=None):
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()
@@ -162,3 +165,17 @@ def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=None)
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
+