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:
authorNathan Vegdahl <cessen@cessen.com>2014-09-26 07:24:03 +0400
committerNathan Vegdahl <cessen@cessen.com>2014-09-26 07:24:03 +0400
commitc35610f163a05f81951a2b069306b675294f4cb3 (patch)
tree645ec626585d90e3ba3c678ee739e9c36e81b7d1 /rigify/rigs
parentfd695c3a81b63db072311e8516e0dbb8d4474047 (diff)
Rigify: new additions from PitchiPoy Animation Productions.
PitchiPoy Animation Productions is sharing its custom rig types with the Blender community at large. The new rig types all start with "pitchipoy." and are used in PitchiPoy's productions. Of particular interest is a face rig type for auto-rigging faces. Other rig types include: - Tentacles - Fingers - Arms/Legs - Spine/Torso Many thanks to PitchiPoy for their hard work and for sharing this back!
Diffstat (limited to 'rigify/rigs')
-rw-r--r--rigify/rigs/biped/arm/__init__.py8
-rw-r--r--rigify/rigs/biped/arm/ik.py2
-rw-r--r--rigify/rigs/biped/leg/__init__.py8
-rw-r--r--rigify/rigs/biped/leg/ik.py2
-rw-r--r--rigify/rigs/biped/limb_common.py124
-rw-r--r--rigify/rigs/pitchipoy/__init__.py0
-rw-r--r--rigify/rigs/pitchipoy/limbs/__init__.py0
-rw-r--r--rigify/rigs/pitchipoy/limbs/arm.py109
-rw-r--r--rigify/rigs/pitchipoy/limbs/leg.py327
-rw-r--r--rigify/rigs/pitchipoy/limbs/limb_utils.py70
-rw-r--r--rigify/rigs/pitchipoy/limbs/paw.py217
-rw-r--r--rigify/rigs/pitchipoy/limbs/super_limb.py724
-rw-r--r--rigify/rigs/pitchipoy/limbs/ui.py51
-rw-r--r--rigify/rigs/pitchipoy/simple_tentacle.py350
-rw-r--r--rigify/rigs/pitchipoy/super_copy.py159
-rw-r--r--rigify/rigs/pitchipoy/super_face.py2388
-rw-r--r--rigify/rigs/pitchipoy/super_finger.py414
-rw-r--r--rigify/rigs/pitchipoy/super_torso_turbo.py901
-rw-r--r--rigify/rigs/pitchipoy/super_widgets.py164
-rw-r--r--rigify/rigs/pitchipoy/tentacle.py509
20 files changed, 6507 insertions, 20 deletions
diff --git a/rigify/rigs/biped/arm/__init__.py b/rigify/rigs/biped/arm/__init__.py
index 3235645e..b6af3fb8 100644
--- a/rigify/rigs/biped/arm/__init__.py
+++ b/rigify/rigs/biped/arm/__init__.py
@@ -56,12 +56,14 @@ if is_selected(fk_arm):
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"]
+hose_arm = ["%s", "%s", "%s", "%s", "%s"]
if is_selected(hose_arm):
- layout.prop(pose_bones[hose_arm[1]], '["smooth_bend"]', text="Smooth Elbow (" + hose_arm[1] + ")", slider=True)
+ layout.prop(pose_bones[hose_arm[2]], '["smooth_bend"]', text="Smooth Elbow (" + hose_arm[2] + ")", slider=True)
"""
end_script = """
@@ -104,7 +106,7 @@ class Rig:
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])
+ 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]
diff --git a/rigify/rigs/biped/arm/ik.py b/rigify/rigs/biped/arm/ik.py
index d5c9509f..a57256ea 100644
--- a/rigify/rigs/biped/arm/ik.py
+++ b/rigify/rigs/biped/arm/ik.py
@@ -59,7 +59,7 @@ class Rig:
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], pole_target_base_name, primary_rotation_axis, bend_hint, layers, ikfk_switch)
+ 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.
diff --git a/rigify/rigs/biped/leg/__init__.py b/rigify/rigs/biped/leg/__init__.py
index 0a9f0ac7..0ddaf3ed 100644
--- a/rigify/rigs/biped/leg/__init__.py
+++ b/rigify/rigs/biped/leg/__init__.py
@@ -60,12 +60,14 @@ if is_selected(fk_leg):
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"]
+hose_leg = ["%s", "%s", "%s", "%s", "%s"]
if is_selected(hose_leg):
- layout.prop(pose_bones[hose_leg[1]], '["smooth_bend"]', text="Smooth Knee (" + hose_leg[1] + ")", slider=True)
+ layout.prop(pose_bones[hose_leg[2]], '["smooth_bend"]', text="Smooth Knee (" + hose_leg[2] + ")", slider=True)
"""
end_script = """
@@ -108,7 +110,7 @@ class Rig:
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])
+ 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]
diff --git a/rigify/rigs/biped/leg/ik.py b/rigify/rigs/biped/leg/ik.py
index aea8502b..b0df999d 100644
--- a/rigify/rigs/biped/leg/ik.py
+++ b/rigify/rigs/biped/leg/ik.py
@@ -91,7 +91,7 @@ class Rig:
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], pole_target_base_name, primary_rotation_axis, bend_hint, self.layers, ikfk_switch)
+ 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.
diff --git a/rigify/rigs/biped/limb_common.py b/rigify/rigs/biped/limb_common.py
index 96033b61..8cd5ad1c 100644
--- a/rigify/rigs/biped/limb_common.py
+++ b/rigify/rigs/biped/limb_common.py
@@ -59,13 +59,15 @@ class FKLimb:
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 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 hinge bones
if parent != None:
socket1 = copy_bone(self.obj, ulimb, make_mechanism_name(ulimb + ".socket1"))
@@ -297,7 +299,7 @@ class IKLimb:
""" An IK limb rig, with an optional ik/fk switch.
"""
- def __init__(self, obj, bone1, bone2, bone3, pole_target_base_name, primary_rotation_axis, bend_hint, layers, ikfk_switch=False):
+ 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
@@ -310,6 +312,8 @@ class IKLimb:
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
@@ -323,6 +327,8 @@ class IKLimb:
if self.org_parent != 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 == None:
+ self.pole_parent = parent
else:
parent = None
@@ -340,6 +346,10 @@ class IKLimb:
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 != 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")))
@@ -358,6 +368,8 @@ class IKLimb:
ulimb_str_e = eb[ulimb_str]
flimb_str_e = eb[flimb_str]
pole_e = eb[pole]
+ if self.pole_parent != None:
+ pole_par_e = eb[pole_par]
viselimb_e = eb[viselimb]
vispole_e = eb[vispole]
@@ -384,8 +396,9 @@ class IKLimb:
flimb_str_e.parent = ulimb_e.parent
pole_e.use_connect = False
- if parent != None:
- pole_e.parent = parent_e
+ if self.pole_parent != None:
+ pole_par_e.parent = None
+ pole_e.parent = pole_par_e
viselimb_e.use_connect = False
viselimb_e.parent = None
@@ -418,6 +431,8 @@ class IKLimb:
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 != 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))
@@ -440,6 +455,8 @@ class IKLimb:
ulimb_str_p = pb[ulimb_str]
flimb_str_p = pb[flimb_str]
pole_p = pb[pole]
+ if self.pole_parent != None:
+ pole_par_p = pb[pole_par]
viselimb_p = pb[viselimb]
vispole_p = pb[vispole]
@@ -489,6 +506,12 @@ class IKLimb:
prop["soft_min"] = prop["min"] = 0.0
prop["soft_max"] = prop["max"] = 1.0
+ if self.pole_parent != 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
@@ -618,6 +641,21 @@ class IKLimb:
con.name = "stretch"
con.owner_space = 'LOCAL'
+ # Pole target parent
+ if self.pole_parent != 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"
@@ -807,25 +845,34 @@ class RubberHoseLimb:
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")))
- uhose_par = copy_bone(self.obj, self.org_bones[0], make_mechanism_name(strip_org(insert_before_lr(uhose, "_parent"))))
- jhose_par = copy_bone(self.obj, junc, make_mechanism_name(strip_org(insert_before_lr(jhose, "_parent"))))
- fhose_par = copy_bone(self.obj, self.org_bones[1], make_mechanism_name(strip_org(insert_before_lr(fhose, "_parent"))))
+ # 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
@@ -847,13 +894,17 @@ class RubberHoseLimb:
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 != None:
@@ -884,6 +935,9 @@ class RubberHoseLimb:
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
@@ -893,6 +947,12 @@ class RubberHoseLimb:
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
@@ -902,6 +962,9 @@ class RubberHoseLimb:
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)
@@ -917,16 +980,22 @@ class RubberHoseLimb:
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)
@@ -949,18 +1018,24 @@ class RubberHoseLimb:
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')
@@ -978,13 +1053,17 @@ class RubberHoseLimb:
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)
@@ -1023,6 +1102,10 @@ class RubberHoseLimb:
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
@@ -1112,11 +1195,11 @@ class RubberHoseLimb:
con = flimb2_p.constraints.new('DAMPED_TRACK')
con.name = "track"
con.target = self.obj
- con.subtarget = self.org_bones[2]
+ con.subtarget = fhoseend
con = flimb2_p.constraints.new('STRETCH_TO')
con.name = "track"
con.target = self.obj
- con.subtarget = self.org_bones[2]
+ con.subtarget = fhoseend
con.volume = 'NO_VOLUME'
con = junc_p.constraints.new('COPY_TRANSFORMS')
@@ -1168,20 +1251,37 @@ class RubberHoseLimb:
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 [uhose, jhose, fhose]
+ return [uhoseend, uhose, jhose, fhose, fhoseend]
diff --git a/rigify/rigs/pitchipoy/__init__.py b/rigify/rigs/pitchipoy/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rigify/rigs/pitchipoy/__init__.py
diff --git a/rigify/rigs/pitchipoy/limbs/__init__.py b/rigify/rigs/pitchipoy/limbs/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/__init__.py
diff --git a/rigify/rigs/pitchipoy/limbs/arm.py b/rigify/rigs/pitchipoy/limbs/arm.py
new file mode 100644
index 00000000..50a11e11
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/arm.py
@@ -0,0 +1,109 @@
+#====================== 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'
+ })
+
+ # Create ik/fk switch property
+ pb = cls.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 = '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
new file mode 100644
index 00000000..5e1844ab
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/leg.py
@@ -0,0 +1,327 @@
+#====================== 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'
+ })
+
+ # 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/limb_utils.py b/rigify/rigs/pitchipoy/limbs/limb_utils.py
new file mode 100644
index 00000000..73e4f472
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/limb_utils.py
@@ -0,0 +1,70 @@
+import bpy, re
+from mathutils import Vector
+from ....utils import org, strip_org, make_mechanism_name, make_deformer_name
+from ....utils import MetarigError
+
+bilateral_suffixes = ['.L','.R']
+
+def orient_bone( cls, eb, axis, scale = 1.0, reverse = False ):
+ v = Vector((0,0,0))
+
+ setattr(v,axis,scale)
+
+ if reverse:
+ tail_vec = v * cls.obj.matrix_world
+ eb.head[:] = eb.tail
+ eb.tail[:] = eb.head + tail_vec
+ else:
+ tail_vec = v * cls.obj.matrix_world
+ eb.tail[:] = eb.head + tail_vec
+
+ eb.roll = 0.0
+
+def make_constraint( cls, bone, constraint ):
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+ pb = cls.obj.pose.bones
+
+ owner_pb = pb[bone]
+ const = owner_pb.constraints.new( constraint['constraint'] )
+
+ constraint['target'] = cls.obj
+
+ # filter contraint props to those that actually exist in the currnet
+ # type of constraint, then assign values to each
+ for p in [ k for k in constraint.keys() if k in dir(const) ]:
+ if p in dir( const ):
+ setattr( const, p, constraint[p] )
+ else:
+ raise MetarigError(
+ "RIGIFY ERROR: property %s does not exist in %s constraint" % (
+ p, constraint['constraint']
+ ))
+
+def get_bone_name( name, btype, suffix = '' ):
+ # RE pattern match right or left parts
+ # match the letter "L" (or "R"), followed by an optional dot (".")
+ # and 0 or more digits at the end of the the string
+ pattern = r'^(\S+)(\.\S+)$'
+
+ name = strip_org( name )
+
+ types = {
+ 'mch' : make_mechanism_name( name ),
+ 'org' : org( name ),
+ 'def' : make_deformer_name( name ),
+ 'ctrl' : name
+ }
+
+ name = types[btype]
+
+ if suffix:
+ results = re.match( pattern, name )
+ bname, addition = ('','')
+
+ if results:
+ bname, addition = results.groups()
+ name = bname + "_" + suffix + addition
+ else:
+ name = name + "_" + suffix
+
+ return name
diff --git a/rigify/rigs/pitchipoy/limbs/paw.py b/rigify/rigs/pitchipoy/limbs/paw.py
new file mode 100644
index 00000000..50b313f8
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/paw.py
@@ -0,0 +1,217 @@
+#====================== 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'] = []
+
+ 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 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
+
+ # 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
+
+ # 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'
+ })
+
+ # Create ik/fk switch property
+ pb = cls.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 = 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'][-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/super_limb.py b/rigify/rigs/pitchipoy/limbs/super_limb.py
new file mode 100644
index 00000000..28e9b70e
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/super_limb.py
@@ -0,0 +1,724 @@
+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
+ 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.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
+ 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' )
+ )
+
+ eb[ mch_str ].tail = eb[ org_bones[-1] ].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
+
+ 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 <= 2:
+ 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 ) ]
+
+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/ui.py b/rigify/rigs/pitchipoy/limbs/ui.py
new file mode 100644
index 00000000..118593ed
--- /dev/null
+++ b/rigify/rigs/pitchipoy/limbs/ui.py
@@ -0,0 +1,51 @@
+script = """
+controls = [%s]
+tweaks = [%s]
+ik_ctrl = '%s'
+fk_ctrl = '%s'
+parent = '%s'
+
+# IK/FK Switch on all Control Bones
+if is_selected( controls ):
+ layout.prop( pose_bones[ parent ], '["%s"]', slider = True )
+
+# BBone rubber hose on each Respective Tweak
+for t in tweaks:
+ if is_selected( t ):
+ layout.prop( pose_bones[ t ], '["%s"]', slider = True )
+
+# IK Stretch on IK Control bone
+if is_selected( ik_ctrl ):
+ layout.prop( pose_bones[ parent ], '["%s"]', slider = True )
+
+# FK limb follow
+if is_selected( fk_ctrl ):
+ layout.prop( pose_bones[ parent ], '["%s"]', slider = True )
+"""
+
+def create_script( bones):
+ # All ctrls have IK/FK switch
+ controls = [ bones['ik']['ctrl']['limb'] ] + bones['fk']['ctrl']
+ controls += bones['ik']['ctrl']['terminal']
+
+ controls_string = ", ".join(["'" + x + "'" for x in controls])
+
+ # All tweaks have their own bbone prop
+ tweaks = bones['tweak']['ctrl'][1:-1]
+ tweaks_string = ", ".join(["'" + x + "'" for x in tweaks])
+
+ # IK ctrl has IK stretch
+ ik_ctrl = bones['ik']['ctrl']['terminal'][-1]
+
+ return script % (
+ controls_string,
+ tweaks_string,
+ ik_ctrl,
+ bones['fk']['ctrl'][0],
+ bones['parent'],
+ 'IK/FK',
+ 'rubber_tweak',
+ 'IK_Strertch',
+ 'FK_limb_follow'
+ )
+
diff --git a/rigify/rigs/pitchipoy/simple_tentacle.py b/rigify/rigs/pitchipoy/simple_tentacle.py
new file mode 100644
index 00000000..4edb15e6
--- /dev/null
+++ b/rigify/rigs/pitchipoy/simple_tentacle.py
@@ -0,0 +1,350 @@
+import bpy
+from ...utils import copy_bone
+from ...utils import strip_org, make_deformer_name, connected_children_names
+from ...utils import make_mechanism_name, put_bone, create_sphere_widget
+from ...utils import create_widget, create_circle_widget
+from ...utils import MetarigError
+from rna_prop_ui import rna_idprop_ui_prop_get
+
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ self.obj = obj
+ self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
+ self.params = params
+
+ self.copy_rotaion_axes = params.copy_rotaion_axes
+
+ if params.tweak_extra_layers:
+ self.tweak_layers = list( params.tweak_layers )
+ else:
+ self.tweak_layers = None
+
+ if len(self.org_bones) <= 1:
+ raise MetarigError(
+ "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
+ )
+
+
+ def make_controls( self ):
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ org_bones = self.org_bones
+
+ ctrl_chain = []
+ for i in range( len( org_bones ) ):
+ name = org_bones[i]
+
+ ctrl_bone = copy_bone(
+ self.obj,
+ name,
+ strip_org(name)
+ )
+
+ ctrl_chain.append( ctrl_bone )
+
+ # Make widgets
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ for ctrl in ctrl_chain:
+ create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5)
+
+ return ctrl_chain
+
+
+ def make_tweaks( self ):
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+ org_bones = self.org_bones
+
+ tweak_chain = []
+ for i in range( len( org_bones ) + 1 ):
+ if i == len( org_bones ):
+ # Make final tweak at the tip of the tentacle
+ name = org_bones[i-1]
+ else:
+ name = org_bones[i]
+
+ tweak_bone = copy_bone(
+ self.obj,
+ name,
+ "tweak_" + strip_org(name)
+ )
+
+ tweak_e = eb[ tweak_bone ]
+
+ tweak_e.length /= 2 # Set size to half
+
+ if i == len( org_bones ):
+ # Position final tweak at the tip
+ put_bone( self.obj, tweak_bone, eb[ org_bones[-1]].tail )
+
+ tweak_chain.append( tweak_bone )
+
+ # Make widgets
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+
+ for tweak in tweak_chain:
+ create_sphere_widget( self.obj, tweak )
+
+ tweak_pb = self.obj.pose.bones[ tweak ]
+
+ # Set locks
+ if tweak_chain.index( tweak ) != len( tweak_chain ) - 1:
+ tweak_pb.lock_rotation = (True, False, True)
+ tweak_pb.lock_scale = (False, True, False)
+ else:
+ tweak_pb.lock_rotation_w = True
+ tweak_pb.lock_rotation = (True, True, True)
+ tweak_pb.lock_scale = (True, True, True)
+
+ # Set up tweak bone layers
+ if self.tweak_layers:
+ tweak_pb.bone.layers = self.tweak_layers
+
+ return tweak_chain
+
+
+ def make_deform( self ):
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ org_bones = self.org_bones
+
+ def_chain = []
+ for i in range( len( org_bones ) ):
+ name = org_bones[i]
+
+ def_bone = copy_bone(
+ self.obj,
+ name,
+ make_deformer_name(strip_org(name))
+ )
+
+ def_chain.append( def_bone )
+
+ return def_chain
+
+
+ def parent_bones( self, all_bones ):
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ org_bones = self.org_bones
+ eb = self.obj.data.edit_bones
+
+ # Parent control bones
+ for bone in all_bones['control'][1:]:
+ previous_index = all_bones['control'].index( bone ) - 1
+ eb[ bone ].parent = eb[ all_bones['control'][previous_index] ]
+
+ # Parent tweak bones
+ tweaks = all_bones['tweak']
+ for tweak in all_bones['tweak']:
+ parent = ''
+ if tweaks.index( tweak ) == len( tweaks ) - 1:
+ parent = all_bones['control'][ -1 ]
+ else:
+ parent = all_bones['control'][ tweaks.index( tweak ) ]
+
+ eb[ tweak ].parent = eb[ parent ]
+
+ # Parent deform bones
+ for bone in all_bones['deform'][1:]:
+ previous_index = all_bones['deform'].index( bone ) - 1
+
+ eb[ bone ].parent = eb[ all_bones['deform'][previous_index] ]
+ eb[ bone ].use_connect = True
+
+ # Parent org bones ( to tweaks by default, or to the controls )
+ for org, tweak in zip( org_bones, all_bones['tweak'] ):
+ eb[ org ].parent = eb[ tweak ]
+
+
+ def make_constraints( self, all_bones ):
+
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ org_bones = self.org_bones
+ pb = self.obj.pose.bones
+
+ # Deform bones' constraints
+ ctrls = all_bones['control']
+ tweaks = all_bones['tweak' ]
+ deforms = all_bones['deform' ]
+
+ for deform, tweak, ctrl in zip( deforms, tweaks, ctrls ):
+ con = pb[deform].constraints.new('COPY_TRANSFORMS')
+ con.target = self.obj
+ con.subtarget = tweak
+
+ con = pb[deform].constraints.new('DAMPED_TRACK')
+ con.target = self.obj
+ con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
+
+ con = pb[deform].constraints.new('STRETCH_TO')
+ con.target = self.obj
+ con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
+
+ # Control bones' constraints
+ if ctrl != ctrls[0]:
+ con = pb[ctrl].constraints.new('COPY_ROTATION')
+ con.target = self.obj
+ con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ]
+ for i, prop in enumerate( [ 'use_x', 'use_y', 'use_z' ] ):
+ if self.copy_rotaion_axes[i]:
+ setattr( con, prop, True )
+ else:
+ setattr( con, prop, False )
+ con.use_offset = True
+ con.target_space = 'LOCAL'
+ con.owner_space = 'LOCAL'
+
+
+
+ def generate(self):
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Clear all initial parenting
+ for bone in self.org_bones:
+ # eb[ bone ].parent = None
+ eb[ bone ].use_connect = False
+
+ # Creating all bones
+ ctrl_chain = self.make_controls()
+ tweak_chain = self.make_tweaks()
+ def_chain = self.make_deform()
+
+ all_bones = {
+ 'control' : ctrl_chain,
+ 'tweak' : tweak_chain,
+ 'deform' : def_chain
+ }
+
+ self.make_constraints( all_bones )
+ self.parent_bones( all_bones )
+
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+ params.copy_rotaion_axes = bpy.props.BoolVectorProperty(
+ size = 3,
+ description = "Layers for the tweak controls to be on",
+ default = tuple( [ i == 0 for i in range(0, 3) ] )
+ )
+
+ # Setting up extra tweak layers
+ params.tweak_extra_layers = bpy.props.BoolProperty(
+ name = "tweak_extra_layers",
+ default = True,
+ description = ""
+ )
+
+ params.tweak_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters.
+ """
+
+ r = layout.row()
+ col = r.column(align=True)
+ row = col.row(align=True)
+ for i,axis in enumerate( [ 'x', 'y', 'z' ] ):
+ row.prop(params, "copy_rotaion_axes", index=i, toggle=True, text=axis)
+
+ r = layout.row()
+ r.prop(params, "tweak_extra_layers")
+ r.active = params.tweak_extra_layers
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range( 8 ): # Layers 0-7
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range( 16, 24 ): # Layers 16-23
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range( 8, 16 ): # Layers 8-15
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range( 24, 32 ): # Layers 24-31
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('Bone')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.0000, 0.3333
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['Bone'] = bone.name
+
+ bone = arm.edit_bones.new('Bone.002')
+ bone.head[:] = 0.0000, 0.0000, 0.3333
+ bone.tail[:] = 0.0000, 0.0000, 0.6667
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['Bone']]
+ bones['Bone.002'] = bone.name
+
+ bone = arm.edit_bones.new('Bone.001')
+ bone.head[:] = 0.0000, 0.0000, 0.6667
+ bone.tail[:] = 0.0000, 0.0000, 1.0000
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['Bone.002']]
+ bones['Bone.001'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['Bone']]
+ pbone.rigify_type = 'pitchipoy.simple_tentacle'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['Bone.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['Bone.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
diff --git a/rigify/rigs/pitchipoy/super_copy.py b/rigify/rigs/pitchipoy/super_copy.py
new file mode 100644
index 00000000..d05d68c4
--- /dev/null
+++ b/rigify/rigs/pitchipoy/super_copy.py
@@ -0,0 +1,159 @@
+#====================== BEGIN GPL LICENSE BLOCK ======================
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+#======================= END GPL LICENSE BLOCK ========================
+
+# <pep8 compliant>
+
+import bpy
+
+from ...utils import copy_bone
+from ...utils import strip_org, make_deformer_name
+from ...utils import create_bone_widget, create_circle_widget
+
+
+class Rig:
+ """ A "copy" rig. All it does is duplicate the original bone and
+ constrain it.
+ This is a control and deformation rig.
+
+ """
+ def __init__(self, obj, bone, params):
+ """ Gather and validate data about the rig.
+ """
+ self.obj = obj
+ self.org_bone = bone
+ self.org_name = strip_org(bone)
+ self.params = params
+ self.make_control = params.make_control
+ self.make_widget = params.make_widget
+ self.make_deform = params.make_deform
+
+ def generate(self):
+ """ Generate the rig.
+ Do NOT modify any of the original bones, except for adding constraints.
+ The main armature should be selected and active before this is called.
+
+ """
+ bpy.ops.object.mode_set(mode='EDIT')
+
+ # Make a control bone (copy of original).
+ if self.make_control:
+ bone = copy_bone(self.obj, self.org_bone, self.org_name)
+
+ # Make a deformation bone (copy of original, child of original).
+ if self.make_deform:
+ def_bone = copy_bone(self.obj, self.org_bone, make_deformer_name(self.org_name))
+
+ # Get edit bones
+ eb = self.obj.data.edit_bones
+ # UNUSED
+ # if self.make_control:
+ # bone_e = eb[bone]
+ if self.make_deform:
+ def_bone_e = eb[def_bone]
+
+ # Parent
+ if self.make_deform:
+ def_bone_e.use_connect = False
+ def_bone_e.parent = eb[self.org_bone]
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pb = self.obj.pose.bones
+
+ if self.make_control:
+ # Constrain the original bone.
+ con = pb[self.org_bone].constraints.new('COPY_TRANSFORMS')
+ con.name = "copy_transforms"
+ con.target = self.obj
+ con.subtarget = bone
+
+ # Create control widget
+ if self.make_widget:
+ create_circle_widget(self.obj, bone, radius = 0.5 )
+ else:
+ create_bone_widget(self.obj, bone, radius = 0.5 )
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+ params.make_control = bpy.props.BoolProperty(
+ name = "Control",
+ default = True,
+ description = "Create a control bone for the copy"
+ )
+
+ params.make_widget = bpy.props.BoolProperty(
+ name = "Widget",
+ default = True,
+ description = "Choose a widget for the bone control"
+ )
+
+ params.make_deform = bpy.props.BoolProperty(
+ name = "Deform",
+ default = True,
+ description = "Create a deform bone for the copy"
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters.
+ """
+ r = layout.row()
+ r.prop(params, "make_control")
+ r = layout.row()
+ r.prop(params, "make_widget")
+ r = layout.row()
+ r.prop(params, "make_deform")
+
+
+def create_sample(obj):
+ """ Create a sample metarig for this rig type.
+ """
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('Bone')
+ bone.head[:] = 0.0000, 0.0000, 0.0000
+ bone.tail[:] = 0.0000, 0.0000, 0.2000
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['Bone'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['Bone']]
+ pbone.rigify_type = 'basic.copy'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
diff --git a/rigify/rigs/pitchipoy/super_face.py b/rigify/rigs/pitchipoy/super_face.py
new file mode 100644
index 00000000..19bf9408
--- /dev/null
+++ b/rigify/rigs/pitchipoy/super_face.py
@@ -0,0 +1,2388 @@
+import bpy, re
+from mathutils import Vector
+from ...utils import copy_bone, flip_bone
+from ...utils import org, strip_org, make_deformer_name, connected_children_names, make_mechanism_name
+from ...utils import create_circle_widget, create_sphere_widget, create_widget, create_cube_widget
+from ...utils import MetarigError
+from rna_prop_ui import rna_idprop_ui_prop_get
+from .super_widgets import create_face_widget, create_eye_widget, create_eyes_widget, create_ear_widget, create_jaw_widget, create_teeth_widget
+
+
+script = """
+all_controls = [%s]
+jaw_ctrl_name = '%s'
+eyes_ctrl_name = '%s'
+
+if is_selected(all_controls):
+ layout.prop(pose_bones[jaw_ctrl_name], '["%s"]', slider=True)
+ layout.prop(pose_bones[eyes_ctrl_name], '["%s"]', slider=True)
+"""
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ self.obj = obj
+
+ b = self.obj.data.bones
+
+ children = [
+ "nose", "lip.T.L", "lip.B.L", "jaw", "ear.L", "ear.R", "lip.T.R",
+ "lip.B.R", "brow.B.L", "lid.T.L", "brow.B.R", "lid.T.R",
+ "forehead.L", "forehead.R", "forehead.L.001", "forehead.R.001",
+ "forehead.L.002", "forehead.R.002", "eye.L", "eye.R", "cheek.T.L",
+ "cheek.T.R", "teeth.T", "teeth.B", "tongue", "temple.L",
+ "temple.R"
+ ]
+
+ #create_pose_lib( self.obj )
+
+ children = [ org(b) for b in children ]
+ grand_children = []
+
+ for child in children:
+ grand_children += connected_children_names( self.obj, child )
+
+ self.org_bones = [bone_name] + children + grand_children
+ self.face_length = obj.data.edit_bones[ self.org_bones[0] ].length
+ self.params = params
+
+ if params.primary_layers_extra:
+ self.primary_layers = list(params.primary_layers)
+ else:
+ self.primary_layers = None
+
+ if params.secondary_layers_extra:
+ self.secondary_layers = list(params.secondary_layers)
+ else:
+ self.secondary_layers = None
+
+ def symmetrical_split( self, bones ):
+
+ # RE pattern match right or left parts
+ # match the letter "L" (or "R"), followed by an optional dot (".")
+ # and 0 or more digits at the end of the the string
+ left_pattern = 'L\.?\d*$'
+ right_pattern = 'R\.?\d*$'
+
+ left = sorted( [ name for name in bones if re.search( left_pattern, name ) ] )
+ right = sorted( [ name for name in bones if re.search( right_pattern, name ) ] )
+
+ return left, right
+
+ def create_deformation( self ):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ def_bones = []
+ for org in org_bones:
+ if 'face' in org or 'teeth' in org or 'eye' in org:
+ continue
+
+ def_name = make_deformer_name( strip_org( org ) )
+ def_name = copy_bone( self.obj, org, def_name )
+ def_bones.append( def_name )
+
+ eb[def_name].use_connect = False
+ eb[def_name].parent = None
+
+ brow_top_names = [ bone for bone in def_bones if 'brow.T' in bone ]
+ forehead_names = [ bone for bone in def_bones if 'forehead' in bone ]
+
+ brow_left, brow_right = self.symmetrical_split( brow_top_names )
+ forehead_left, forehead_right = self.symmetrical_split( forehead_names )
+
+ brow_left = brow_left[1:]
+ brow_right = brow_right[1:]
+ brow_left.reverse()
+ brow_right.reverse()
+
+ for browL, browR, foreheadL, foreheadR in zip(
+ brow_left, brow_right, forehead_left, forehead_right ):
+
+ eb[foreheadL].tail = eb[browL].head
+ eb[foreheadR].tail = eb[browR].head
+
+ return { 'all' : def_bones }
+
+
+ def create_ctrl( self, bones ):
+ org_bones = self.org_bones
+
+ ## create control bones
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # eyes ctrls
+ eyeL_e = eb[ bones['eyes'][0] ]
+ eyeR_e = eb[ bones['eyes'][1] ]
+
+ distance = ( eyeL_e.head - eyeR_e.head ) * 3
+ distance = distance.cross( (0, 0, 1) )
+
+ eyeL_ctrl_name = strip_org( bones['eyes'][0] )
+ eyeR_ctrl_name = strip_org( bones['eyes'][1] )
+
+ eyeL_ctrl_name = copy_bone( self.obj, bones['eyes'][0], eyeL_ctrl_name )
+ eyeR_ctrl_name = copy_bone( self.obj, bones['eyes'][1], eyeR_ctrl_name )
+ eyes_ctrl_name = copy_bone( self.obj, bones['eyes'][0], 'eyes' )
+
+ eyeL_ctrl_e = eb[ eyeL_ctrl_name ]
+ eyeR_ctrl_e = eb[ eyeR_ctrl_name ]
+ eyes_ctrl_e = eb[ 'eyes' ]
+
+ eyeL_ctrl_e.head += distance
+ eyeR_ctrl_e.head += distance
+ eyes_ctrl_e.head[:] = ( eyeL_ctrl_e.head + eyeR_ctrl_e.head ) / 2
+
+ for bone in [ eyeL_ctrl_e, eyeR_ctrl_e, eyes_ctrl_e ]:
+ bone.tail[:] = bone.head + Vector( [ 0, 0, eyeL_e.length * 0.75 ] )
+
+ ## Widget for transforming the both eyes
+ eye_master_names = []
+ for bone in bones['eyes']:
+ eye_master = copy_bone(
+ self.obj,
+ bone,
+ 'master_' + strip_org(bone)
+ )
+
+ eye_master_names.append( eye_master )
+
+ ## turbo: adding a master nose for transforming the whole nose
+ master_nose = copy_bone(self.obj, 'ORG-nose.004', 'nose_master')
+ eb[master_nose].tail[:] = \
+ eb[master_nose].head + Vector([0, self.face_length / -4, 0])
+
+ # ears ctrls
+ earL_name = strip_org( bones['ears'][0] )
+ earR_name = strip_org( bones['ears'][1] )
+
+ earL_ctrl_name = copy_bone( self.obj, org( bones['ears'][0] ), earL_name )
+ earR_ctrl_name = copy_bone( self.obj, org( bones['ears'][1] ), earR_name )
+
+ # jaw ctrl
+ jaw_ctrl_name = strip_org( bones['jaw'][2] ) + '_master'
+ jaw_ctrl_name = copy_bone( self.obj, bones['jaw'][2], jaw_ctrl_name )
+
+ jawL_org_e = eb[ bones['jaw'][0] ]
+ jawR_org_e = eb[ bones['jaw'][1] ]
+ jaw_org_e = eb[ bones['jaw'][2] ]
+
+ eb[ jaw_ctrl_name ].head[:] = ( jawL_org_e.head + jawR_org_e.head ) / 2
+
+ # teeth ctrls
+ teethT_name = strip_org( bones['teeth'][0] )
+ teethB_name = strip_org( bones['teeth'][1] )
+
+ teethT_ctrl_name = copy_bone( self.obj, org( bones['teeth'][0] ), teethT_name )
+ teethB_ctrl_name = copy_bone( self.obj, org( bones['teeth'][1] ), teethB_name )
+
+ # tongue ctrl
+ tongue_org = bones['tongue'].pop()
+ tongue_name = strip_org( tongue_org ) + '_master'
+
+ tongue_ctrl_name = copy_bone( self.obj, tongue_org, tongue_name )
+
+ flip_bone( self.obj, tongue_ctrl_name )
+
+ ## Assign widgets
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ # Assign each eye widgets
+ create_eye_widget( self.obj, eyeL_ctrl_name )
+ create_eye_widget( self.obj, eyeR_ctrl_name )
+
+ # Assign eyes widgets
+ create_eyes_widget( self.obj, eyes_ctrl_name )
+
+ # Assign each eye_master widgets
+ for master in eye_master_names:
+ create_square_widget(self.obj, master)
+
+ # Assign nose_master widget
+ create_square_widget( self.obj, master_nose, size = 1 )
+
+ # Assign ears widget
+ create_ear_widget( self.obj, earL_ctrl_name )
+ create_ear_widget( self.obj, earR_ctrl_name )
+
+ # Assign jaw widget
+ create_jaw_widget( self.obj, jaw_ctrl_name )
+
+ # Assign teeth widget
+ create_teeth_widget( self.obj, teethT_ctrl_name )
+ create_teeth_widget( self.obj, teethB_ctrl_name )
+
+ # Assign tongue widget ( using the jaw widget )
+ create_jaw_widget( self.obj, tongue_ctrl_name )
+
+ return {
+ 'eyes' : [
+ eyeL_ctrl_name,
+ eyeR_ctrl_name,
+ eyes_ctrl_name,
+ ] + eye_master_names,
+ 'ears' : [ earL_ctrl_name, earR_ctrl_name ],
+ 'jaw' : [ jaw_ctrl_name ],
+ 'teeth' : [ teethT_ctrl_name, teethB_ctrl_name ],
+ 'tongue' : [ tongue_ctrl_name ],
+ 'nose' : [ master_nose ]
+ }
+
+
+ def create_tweak( self, bones, uniques, tails ):
+ org_bones = self.org_bones
+
+ ## create tweak bones
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ tweaks = []
+
+ for bone in bones + list( uniques.keys() ):
+
+ tweak_name = strip_org( bone )
+
+ # pick name for unique bone from the uniques dictionary
+ if bone in list( uniques.keys() ):
+ tweak_name = uniques[bone]
+
+ tweak_name = copy_bone( self.obj, bone, tweak_name )
+ eb[ tweak_name ].use_connect = False
+ eb[ tweak_name ].parent = None
+
+ tweaks.append( tweak_name )
+
+ eb[ tweak_name ].tail[:] = \
+ eb[ tweak_name ].head + Vector(( 0, 0, self.face_length / 7 ))
+
+ # create tail bone
+ if bone in tails:
+ if 'lip.T.L.001' in bone:
+ tweak_name = copy_bone( self.obj, bone, 'lips.L' )
+ elif 'lip.T.R.001' in bone:
+ tweak_name = copy_bone( self.obj, bone, 'lips.R' )
+ else:
+ tweak_name = copy_bone( self.obj, bone, tweak_name )
+
+ eb[ tweak_name ].use_connect = False
+ eb[ tweak_name ].parent = None
+
+ eb[ tweak_name ].head = eb[ bone ].tail
+ eb[ tweak_name ].tail[:] = \
+ eb[ tweak_name ].head + Vector(( 0, 0, self.face_length / 7 ))
+
+ tweaks.append( tweak_name )
+
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ pb = self.obj.pose.bones
+
+ primary_tweaks = [
+ "lid.B.L.002", "lid.T.L.002", "lid.B.R.002", "lid.T.R.002",
+ "chin", "brow.T.L.001", "brow.T.L.002", "brow.T.L.003",
+ "brow.T.R.001", "brow.T.R.002", "brow.T.R.003", "lip.B",
+ "lip.B.L.001", "lip.B.R.001", "cheek.B.L.001", "cheek.B.R.001",
+ "lips.L", "lips.R", "lip.T.L.001", "lip.T.R.001", "lip.T",
+ "nose.002", "nose.L.001", "nose.R.001"
+ ]
+
+ for bone in tweaks:
+ if bone in primary_tweaks:
+ if self.primary_layers:
+ pb[bone].bone.layers = self.primary_layers
+ create_face_widget( self.obj, bone, size = 1.5 )
+ else:
+ if self.secondary_layers:
+ pb[bone].bone.layers = self.secondary_layers
+ create_face_widget( self.obj, bone )
+
+ return { 'all' : tweaks }
+
+
+ def all_controls( self ):
+ org_bones = self.org_bones
+
+ org_tongue_bones = sorted([ bone for bone in org_bones if 'tongue' in bone ])
+
+ org_to_ctrls = {
+ 'eyes' : [ 'eye.L', 'eye.R' ],
+ 'ears' : [ 'ear.L', 'ear.R' ],
+ 'jaw' : [ 'jaw.L', 'jaw.R', 'jaw' ],
+ 'teeth' : [ 'teeth.T', 'teeth.B' ],
+ 'tongue' : [ org_tongue_bones[0] ]
+ }
+
+ tweak_unique = { 'lip.T.L' : 'lip.T',
+ 'lip.B.L' : 'lip.B' }
+
+ org_to_ctrls = { key : [ org( bone ) for bone in org_to_ctrls[key] ] for key in org_to_ctrls.keys() }
+ tweak_unique = { org( key ) : tweak_unique[key] for key in tweak_unique.keys() }
+
+ tweak_exceptions = [] # bones not used to create tweaks
+ tweak_exceptions += [ bone for bone in org_bones if 'forehead' in bone or 'temple' in bone ]
+
+ tweak_tail = [ 'brow.B.L.003', 'brow.B.R.003', 'nose.004', 'chin.001' ]
+ tweak_tail += [ 'lip.T.L.001', 'lip.T.R.001', 'tongue.002' ]
+
+ tweak_exceptions += [ 'lip.T.R', 'lip.B.R', 'ear.L.001', 'ear.R.001' ] + list(tweak_unique.keys())
+ tweak_exceptions += [ 'face', 'cheek.T.L', 'cheek.T.R', 'cheek.B.L', 'cheek.B.R' ]
+ tweak_exceptions += [ 'ear.L', 'ear.R', 'eye.L', 'eye.R' ]
+
+ tweak_exceptions += org_to_ctrls.keys()
+ tweak_exceptions += org_to_ctrls['teeth']
+
+ tweak_exceptions.pop( tweak_exceptions.index('tongue') )
+ tweak_exceptions.pop( tweak_exceptions.index('jaw') )
+
+ tweak_exceptions = [ org( bone ) for bone in tweak_exceptions ]
+ tweak_tail = [ org( bone ) for bone in tweak_tail ]
+
+ org_to_tweak = sorted( [ bone for bone in org_bones if bone not in tweak_exceptions ] )
+
+ ctrls = self.create_ctrl( org_to_ctrls )
+ tweaks = self.create_tweak( org_to_tweak, tweak_unique, tweak_tail )
+
+ return { 'ctrls' : ctrls, 'tweaks' : tweaks }, tweak_unique
+
+ def create_mch( self, jaw_ctrl, tongue_ctrl ):
+ org_bones = self.org_bones
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Create eyes mch bones
+ eyes = [ bone for bone in org_bones if 'eye' in bone ]
+
+ mch_bones = { strip_org( eye ) : [] for eye in eyes }
+
+ for eye in eyes:
+ mch_name = make_mechanism_name( strip_org( eye ) )
+ mch_name = copy_bone( self.obj, eye, mch_name )
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ mch_bones[ strip_org( eye ) ].append( mch_name )
+
+ mch_name = copy_bone( self.obj, eye, mch_name )
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ mch_bones[ strip_org( eye ) ].append( mch_name )
+
+ eb[ mch_name ].head[:] = eb[ mch_name ].tail
+ eb[ mch_name ].tail[:] = eb[ mch_name ].head + Vector( ( 0, 0, 0.005 ) )
+
+ # Create the eyes' parent mch
+ face = [ bone for bone in org_bones if 'face' in bone ].pop()
+
+ mch_name = 'eyes_parent'
+ mch_name = make_mechanism_name( mch_name )
+ mch_name = copy_bone( self.obj, face, mch_name )
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ eb[ mch_name ].length /= 4
+
+ mch_bones['eyes_parent'] = [ mch_name ]
+
+ # Create the lids' mch bones
+ all_lids = [ bone for bone in org_bones if 'lid' in bone ]
+ lids_L, lids_R = self.symmetrical_split( all_lids )
+
+ all_lids = [ lids_L, lids_R ]
+
+ mch_bones['lids'] = []
+
+ for i in range( 2 ):
+ for bone in all_lids[i]:
+ mch_name = make_mechanism_name( strip_org( bone ) )
+ mch_name = copy_bone( self.obj, eyes[i], mch_name )
+
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ eb[ mch_name ].tail[:] = eb[ bone ].head
+
+ mch_bones['lids'].append( mch_name )
+
+ mch_bones['jaw'] = []
+
+ length_subtractor = eb[ jaw_ctrl ].length / 6
+ # Create the jaw mch bones
+ for i in range( 6 ):
+ if i == 0:
+ mch_name = make_mechanism_name( 'mouth_lock' )
+ else:
+ mch_name = make_mechanism_name( jaw_ctrl )
+
+ mch_name = copy_bone( self.obj, jaw_ctrl, mch_name )
+
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ eb[ mch_name ].length = eb[ jaw_ctrl ].length - length_subtractor * i
+
+ mch_bones['jaw'].append( mch_name )
+
+ # Tongue mch bones
+
+ mch_bones['tongue'] = []
+
+ # create mch bones for all tongue org_bones except the first one
+ for bone in sorted([ org for org in org_bones if 'tongue' in org ])[1:]:
+ mch_name = make_mechanism_name( strip_org( bone ) )
+ mch_name = copy_bone( self.obj, tongue_ctrl, mch_name )
+
+ eb[ mch_name ].use_connect = False
+ eb[ mch_name ].parent = None
+
+ mch_bones['tongue'].append( mch_name )
+
+ return mch_bones
+
+ def parent_bones( self, all_bones, tweak_unique ):
+ org_bones = self.org_bones
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ face_name = [ bone for bone in org_bones if 'face' in bone ].pop()
+
+ # Initially parenting all bones to the face org bone.
+ for category in list( all_bones.keys() ):
+ for area in list( all_bones[category] ):
+ for bone in all_bones[category][area]:
+ eb[ bone ].parent = eb[ face_name ]
+
+ ## Parenting all deformation bones and org bones
+
+ # Parent all the deformation bones that have respective tweaks
+ def_tweaks = [ bone for bone in all_bones['deform']['all'] if bone[4:] in all_bones['tweaks']['all'] ]
+
+ # Parent all org bones to the ORG-face
+ for bone in [ bone for bone in org_bones if 'face' not in bone ]:
+ eb[ bone ].parent = eb[ org('face') ]
+
+ for bone in def_tweaks:
+ # the def and the matching org bone are parented to their corresponding tweak,
+ # whose name is the same as that of the def bone, without the "DEF-" (first 4 chars)
+ eb[ bone ].parent = eb[ bone[4:] ]
+ eb[ org( bone[4:] ) ].parent = eb[ bone[4:] ]
+
+ # Parent ORG eyes to corresponding mch bones
+ for bone in [ bone for bone in org_bones if 'eye' in bone ]:
+ eb[ bone ].parent = eb[ make_mechanism_name( strip_org( bone ) ) ]
+
+ for lip_tweak in list( tweak_unique.values() ):
+ # find the def bones that match unique lip_tweaks by slicing [4:-2]
+ # example: 'lip.B' matches 'DEF-lip.B.R' and 'DEF-lip.B.L' if
+ # you cut off the "DEF-" [4:] and the ".L" or ".R" [:-2]
+ lip_defs = [ bone for bone in all_bones['deform']['all'] if bone[4:-2] == lip_tweak ]
+
+ for bone in lip_defs:
+ eb[bone].parent = eb[ lip_tweak ]
+
+ # parent cheek bones top respetive tweaks
+ lips = [ 'lips.L', 'lips.R' ]
+ brows = [ 'brow.T.L', 'brow.T.R' ]
+ cheekB_defs = [ 'DEF-cheek.B.L', 'DEF-cheek.B.R' ]
+ cheekT_defs = [ 'DEF-cheek.T.L', 'DEF-cheek.T.R' ]
+
+ for lip, brow, cheekB, cheekT in zip( lips, brows, cheekB_defs, cheekT_defs ):
+ eb[ cheekB ].parent = eb[ lip ]
+ eb[ cheekT ].parent = eb[ brow ]
+
+ # parent ear deform bones to their controls
+ ear_defs = [ 'DEF-ear.L', 'DEF-ear.L.001', 'DEF-ear.R', 'DEF-ear.R.001' ]
+ ear_ctrls = [ 'ear.L', 'ear.R' ]
+
+ eb[ 'DEF-jaw' ].parent = eb[ 'jaw' ] # Parent jaw def bone to jaw tweak
+
+ for ear_ctrl in ear_ctrls:
+ for ear_def in ear_defs:
+ if ear_ctrl in ear_def:
+ eb[ ear_def ].parent = eb[ ear_ctrl ]
+
+ # Parent eyelid deform bones (each lid def bone is parented to its respective MCH bone)
+ def_lids = [ bone for bone in all_bones['deform']['all'] if 'lid' in bone ]
+
+ for bone in def_lids:
+ mch = make_mechanism_name( bone[4:] )
+ eb[ bone ].parent = eb[ mch ]
+
+ ## Parenting all mch bones
+
+ eb[ 'MCH-eyes_parent' ].parent = None # eyes_parent will be parented to root
+
+ # parent all mch tongue bones to the jaw master control bone
+ for bone in all_bones['mch']['tongue']:
+ eb[ bone ].parent = eb[ all_bones['ctrls']['jaw'][0] ]
+
+ ## Parenting the control bones
+
+ # parent teeth.B and tongue master controls to the jaw master control bone
+ for bone in [ 'teeth.B', 'tongue_master' ]:
+ eb[ bone ].parent = eb[ all_bones['ctrls']['jaw'][0] ]
+
+ # eyes
+ eb[ 'eyes' ].parent = eb[ 'MCH-eyes_parent' ]
+
+ eyes = [
+ bone for bone in all_bones['ctrls']['eyes'] if 'eyes' not in bone
+ ][0:2]
+
+ for eye in eyes:
+ eb[ eye ].parent = eb[ 'eyes' ]
+
+ ## turbo: parent eye master bones to face
+ for eye_master in eyes[2:]:
+ eb[ eye_master ].parent = eb[ 'ORG-face' ]
+
+ # Parent brow.b, eyes mch and lid tweaks and mch bones to masters
+ tweaks = [
+ b for b in all_bones['tweaks']['all'] if 'lid' in b or 'brow.B' in b
+ ]
+ mch = all_bones['mch']['lids'] + \
+ all_bones['mch']['eye.R'] + \
+ all_bones['mch']['eye.L']
+
+ everyone = tweaks + mch
+
+ left, right = self.symmetrical_split( everyone )
+
+ for l in left:
+ eb[ l ].parent = eb[ 'master_eye.L' ]
+
+ for r in right:
+ eb[ r ].parent = eb[ 'master_eye.R' ]
+
+ ## turbo: nose to mch jaw.004
+ eb[ all_bones['ctrls']['nose'].pop() ].parent = eb['MCH-jaw_master.004']
+
+ ## Parenting the tweak bones
+
+ # Jaw children (values) groups and their parents (keys)
+ groups = {
+ 'jaw_master' : [
+ 'jaw',
+ 'jaw.R.001',
+ 'jaw.L.001',
+ 'chin.L',
+ 'chin.R',
+ 'chin',
+ 'tongue.003'
+ ],
+ 'MCH-jaw_master' : [
+ 'lip.B'
+ ],
+ 'MCH-jaw_master.001' : [
+ 'lip.B.L.001',
+ 'lip.B.R.001'
+ ],
+ 'MCH-jaw_master.002' : [
+ 'lips.L',
+ 'lips.R',
+ 'cheek.B.L.001',
+ 'cheek.B.R.001'
+ ],
+ 'MCH-jaw_master.003' : [
+ 'lip.T',
+ 'lip.T.L.001',
+ 'lip.T.R.001'
+ ],
+ 'MCH-jaw_master.004' : [
+ 'cheek.T.L.001',
+ 'cheek.T.R.001'
+ ],
+ 'nose_master' : [
+ 'nose.002',
+ 'nose.004',
+ 'nose.L.001',
+ 'nose.R.001'
+ ]
+ }
+
+ for parent in list( groups.keys() ):
+ for bone in groups[parent]:
+ eb[ bone ].parent = eb[ parent ]
+
+ # Remaining arbitrary relatioships for tweak bone parenting
+ eb[ 'chin.001' ].parent = eb[ 'chin' ]
+ eb[ 'chin.002' ].parent = eb[ 'lip.B' ]
+ eb[ 'nose.001' ].parent = eb[ 'nose.002' ]
+ eb[ 'nose.003' ].parent = eb[ 'nose.002' ]
+ eb[ 'nose.005' ].parent = eb[ 'lip.T' ]
+ eb[ 'tongue' ].parent = eb[ 'tongue_master' ]
+ eb[ 'tongue.001' ].parent = eb[ 'MCH-tongue.001' ]
+ eb[ 'tongue.002' ].parent = eb[ 'MCH-tongue.002' ]
+
+ for bone in [ 'ear.L.002', 'ear.L.003', 'ear.L.004' ]:
+ eb[ bone ].parent = eb[ 'ear.L' ]
+ eb[ bone.replace( '.L', '.R' ) ].parent = eb[ 'ear.R' ]
+
+
+ def make_constraits( self, constraint_type, bone, subtarget, influence = 1 ):
+ org_bones = self.org_bones
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ pb = self.obj.pose.bones
+
+ owner_pb = pb[bone]
+
+ if constraint_type == 'def_tweak':
+
+ const = owner_pb.constraints.new( 'DAMPED_TRACK' )
+ const.target = self.obj
+ const.subtarget = subtarget
+
+ const = owner_pb.constraints.new( 'STRETCH_TO' )
+ const.target = self.obj
+ const.subtarget = subtarget
+
+ elif constraint_type == 'def_lids':
+
+ const = owner_pb.constraints.new( 'DAMPED_TRACK' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.head_tail = 1.0
+
+ const = owner_pb.constraints.new( 'STRETCH_TO' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.head_tail = 1.0
+
+ elif constraint_type == 'mch_eyes':
+
+ const = owner_pb.constraints.new( 'DAMPED_TRACK' )
+ const.target = self.obj
+ const.subtarget = subtarget
+
+ elif constraint_type == 'mch_eyes_lids_follow':
+
+ const = owner_pb.constraints.new( 'COPY_LOCATION' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.head_tail = 1.0
+
+ elif constraint_type == 'mch_eyes_parent':
+
+ const = owner_pb.constraints.new( 'COPY_TRANSFORMS' )
+ const.target = self.obj
+ const.subtarget = subtarget
+
+ elif constraint_type == 'mch_jaw_master':
+
+ const = owner_pb.constraints.new( 'COPY_TRANSFORMS' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.influence = influence
+
+ elif constraint_type == 'tweak_copyloc':
+
+ const = owner_pb.constraints.new( 'COPY_LOCATION' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.influence = influence
+ const.use_offset = True
+ const.target_space = 'LOCAL'
+ const.owner_space = 'LOCAL'
+
+ elif constraint_type == 'tweak_copy_rot_scl':
+
+ const = owner_pb.constraints.new( 'COPY_ROTATION' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.use_offset = True
+ const.target_space = 'LOCAL'
+ const.owner_space = 'LOCAL'
+
+ const = owner_pb.constraints.new( 'COPY_SCALE' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.use_offset = True
+ const.target_space = 'LOCAL'
+ const.owner_space = 'LOCAL'
+
+ elif constraint_type == 'tweak_copyloc_inv':
+
+ const = owner_pb.constraints.new( 'COPY_LOCATION' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.influence = influence
+ const.target_space = 'LOCAL'
+ const.owner_space = 'LOCAL'
+ const.use_offset = True
+ const.invert_x = True
+ const.invert_y = True
+ const.invert_z = True
+
+ elif constraint_type == 'mch_tongue_copy_trans':
+
+ const = owner_pb.constraints.new( 'COPY_TRANSFORMS' )
+ const.target = self.obj
+ const.subtarget = subtarget
+ const.influence = influence
+
+
+ def constraints( self, all_bones ):
+ ## Def bone constraints
+
+ def_specials = {
+ # 'bone' : 'target'
+ 'DEF-jaw' : 'chin',
+ 'DEF-chin.L' : 'lips.L',
+ 'DEF-jaw.L.001' : 'chin.L',
+ 'DEF-chin.R' : 'lips.R',
+ 'DEF-jaw.R.001' : 'chin.R',
+ 'DEF-brow.T.L.003' : 'nose',
+ 'DEF-ear.L.003' : 'ear.L.004',
+ 'DEF-ear.L.004' : 'ear.L',
+ 'DEF-ear.R.003' : 'ear.R.004',
+ 'DEF-ear.R.004' : 'ear.R',
+ 'DEF-lip.B.L.001' : 'lips.L',
+ 'DEF-lip.B.R.001' : 'lips.R',
+ 'DEF-cheek.B.L.001' : 'brow.T.L',
+ 'DEF-cheek.B.R.001' : 'brow.T.R',
+ 'DEF-lip.T.L.001' : 'lips.L',
+ 'DEF-lip.T.R.001' : 'lips.R',
+ 'DEF-cheek.T.L.001' : 'nose.L',
+ 'DEF-nose.L.001' : 'nose.002',
+ 'DEF-cheek.T.R.001' : 'nose.R',
+ 'DEF-nose.R.001' : 'nose.002',
+ 'DEF-forehead.L' : 'brow.T.L.003',
+ 'DEF-forehead.L.001' : 'brow.T.L.002',
+ 'DEF-forehead.L.002' : 'brow.T.L.001',
+ 'DEF-temple.L' : 'jaw.L',
+ 'DEF-brow.T.R.003' : 'nose',
+ 'DEF-forehead.R' : 'brow.T.R.003',
+ 'DEF-forehead.R.001' : 'brow.T.R.002',
+ 'DEF-forehead.R.002' : 'brow.T.R.001',
+ 'DEF-temple.R' : 'jaw.R'
+ }
+
+ pattern = r'^DEF-(\w+\.?\w?\.?\w?)(\.?)(\d*?)(\d?)$'
+
+ for bone in [ bone for bone in all_bones['deform']['all'] if 'lid' not in bone ]:
+ if bone in list( def_specials.keys() ):
+ self.make_constraits('def_tweak', bone, def_specials[bone] )
+ else:
+ matches = re.match( pattern, bone ).groups()
+ if len( matches ) > 1 and matches[-1]:
+ num = int( matches[-1] ) + 1
+ str_list = list( matches )[:-1] + [ str( num ) ]
+ tweak = "".join( str_list )
+ else:
+ tweak = "".join( matches ) + ".001"
+ self.make_constraits('def_tweak', bone, tweak )
+
+ def_lids = sorted( [ bone for bone in all_bones['deform']['all'] if 'lid' in bone ] )
+ mch_lids = sorted( [ bone for bone in all_bones['mch']['lids'] ] )
+
+ def_lidsL, def_lidsR = self.symmetrical_split( def_lids )
+ mch_lidsL, mch_lidsR = self.symmetrical_split( mch_lids )
+
+ # Take the last mch_lid bone and place it at the end
+ mch_lidsL = mch_lidsL[1:] + [ mch_lidsL[0] ]
+ mch_lidsR = mch_lidsR[1:] + [ mch_lidsR[0] ]
+
+ for boneL, boneR, mchL, mchR in zip( def_lidsL, def_lidsR, mch_lidsL, mch_lidsR ):
+ self.make_constraits('def_lids', boneL, mchL )
+ self.make_constraits('def_lids', boneR, mchR )
+
+ ## MCH constraints
+
+ # mch lids constraints
+ for bone in all_bones['mch']['lids']:
+ tweak = bone[4:] # remove "MCH-" from bone name
+ self.make_constraits('mch_eyes', bone, tweak )
+
+ # mch eyes constraints
+ for bone in [ 'MCH-eye.L', 'MCH-eye.R' ]:
+ ctrl = bone[4:] # remove "MCH-" from bone name
+ self.make_constraits('mch_eyes', bone, ctrl )
+
+ for bone in [ 'MCH-eye.L.001', 'MCH-eye.R.001' ]:
+ target = bone[:-4] # remove number from the end of the name
+ self.make_constraits('mch_eyes_lids_follow', bone, target )
+
+ # mch eyes parent constraints
+ self.make_constraits('mch_eyes_parent', 'MCH-eyes_parent', 'ORG-face' )
+
+ ## Jaw constraints
+
+ # jaw master mch bones
+ self.make_constraits( 'mch_jaw_master', 'MCH-mouth_lock', 'jaw_master', 0.20 )
+ self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master', 'jaw_master', 1.00 )
+ self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.001', 'jaw_master', 0.75 )
+ self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.002', 'jaw_master', 0.35 )
+ self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.003', 'jaw_master', 0.10 )
+ self.make_constraits( 'mch_jaw_master', 'MCH-jaw_master.004', 'jaw_master', 0.025 )
+
+ for bone in all_bones['mch']['jaw'][1:-1]:
+ self.make_constraits( 'mch_jaw_master', bone, 'MCH-mouth_lock' )
+
+ ## Tweak bones constraints
+
+ # copy location constraints for tweak bones of both sides
+ tweak_copyloc_L = {
+ 'brow.T.L.002' : [ [ 'brow.T.L.001', 'brow.T.L.003' ], [ 0.5, 0.5 ] ],
+ 'ear.L.003' : [ [ 'ear.L.004', 'ear.L.002' ], [ 0.5, 0.5 ] ],
+ 'brow.B.L.001' : [ [ 'brow.B.L.002' ], [ 0.6 ] ],
+ 'brow.B.L.003' : [ [ 'brow.B.L.002' ], [ 0.6 ] ],
+ 'brow.B.L.002' : [ [ 'lid.T.L.001', ], [ 0.25 ] ],
+ 'brow.B.L.002' : [ [ 'brow.T.L.002', ], [ 0.25 ] ],
+ 'lid.T.L.001' : [ [ 'lid.T.L.002' ], [ 0.6 ] ],
+ 'lid.T.L.003' : [ [ 'lid.T.L.002', ], [ 0.6 ] ],
+ 'lid.T.L.002' : [ [ 'MCH-eye.L.001', ], [ 0.5 ] ],
+ 'lid.B.L.001' : [ [ 'lid.B.L.002', ], [ 0.6 ] ],
+ 'lid.B.L.003' : [ [ 'lid.B.L.002', ], [ 0.6 ] ],
+ 'lid.B.L.002' : [ [ 'MCH-eye.L.001', 'cheek.T.L.001' ], [ 0.5, 0.1 ] ],
+ 'cheek.T.L.001' : [ [ 'cheek.B.L.001', ], [ 0.5 ] ],
+ 'nose.L' : [ [ 'nose.L.001', ], [ 0.25 ] ],
+ 'nose.L.001' : [ [ 'lip.T.L.001', ], [ 0.2 ] ],
+ 'cheek.B.L.001' : [ [ 'lips.L', ], [ 0.5 ] ],
+ 'lip.T.L.001' : [ [ 'lips.L', 'lip.T' ], [ 0.25, 0.5 ] ],
+ 'lip.B.L.001' : [ [ 'lips.L', 'lip.B' ], [ 0.25, 0.5 ] ]
+ }
+
+ for owner in list( tweak_copyloc_L.keys() ):
+
+ targets, influences = tweak_copyloc_L[owner]
+ for target, influence in zip( targets, influences ):
+
+ # Left side constraints
+ self.make_constraits( 'tweak_copyloc', owner, target, influence )
+
+ # create constraints for the right side too
+ ownerR = owner.replace( '.L', '.R' )
+ targetR = target.replace( '.L', '.R' )
+ self.make_constraits( 'tweak_copyloc', ownerR, targetR, influence )
+
+ # copy rotation & scale constraints for tweak bones of both sides
+ tweak_copy_rot_scl_L = {
+ 'lip.T.L.001' : 'lip.T',
+ 'lip.B.L.001' : 'lip.B'
+ }
+
+ for owner in list( tweak_copy_rot_scl_L.keys() ):
+ target = tweak_copy_rot_scl_L[owner]
+ influence = tweak_copy_rot_scl_L[owner]
+ self.make_constraits( 'tweak_copy_rot_scl', owner, target )
+
+ # create constraints for the right side too
+ owner = owner.replace( '.L', '.R' )
+ self.make_constraits( 'tweak_copy_rot_scl', owner, target )
+
+ # inverted tweak bones constraints
+ tweak_nose = {
+ 'nose.001' : [ 'nose.002', 0.35 ],
+ 'nose.003' : [ 'nose.002', 0.5 ],
+ 'nose.005' : [ 'lip.T', 0.5 ],
+ 'chin.002' : [ 'lip.B', 0.5 ]
+ }
+
+ for owner in list( tweak_nose.keys() ):
+ target = tweak_nose[owner][0]
+ influence = tweak_nose[owner][1]
+ self.make_constraits( 'tweak_copyloc_inv', owner, target, influence )
+
+ # MCH tongue constraints
+ divider = len( all_bones['mch']['tongue'] ) + 1
+ factor = len( all_bones['mch']['tongue'] )
+
+ for owner in all_bones['mch']['tongue']:
+ self.make_constraits( 'mch_tongue_copy_trans', owner, 'tongue_master', ( 1 / divider ) * factor )
+ factor -= 1
+
+
+ def drivers_and_props( self, all_bones ):
+
+ bpy.ops.object.mode_set(mode ='OBJECT')
+ pb = self.obj.pose.bones
+
+ jaw_ctrl = all_bones['ctrls']['jaw'][0]
+ eyes_ctrl = all_bones['ctrls']['eyes'][2]
+
+ jaw_prop = 'mouth_lock'
+ eyes_prop = 'eyes_follow'
+
+ for bone, prop_name in zip( [ jaw_ctrl, eyes_ctrl ], [ jaw_prop, eyes_prop ] ):
+ if bone == jaw_ctrl:
+ pb[ bone ][ prop_name ] = 0.0
+ else:
+ pb[ bone ][ prop_name ] = 1.0
+
+ prop = rna_idprop_ui_prop_get( pb[ bone ], prop_name )
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["description"] = prop_name
+
+ # Jaw drivers
+ mch_jaws = all_bones['mch']['jaw'][1:-1]
+
+ for bone in mch_jaws:
+ drv = pb[ bone ].constraints[1].driver_add("influence").driver
+ drv.type='SUM'
+
+ var = drv.variables.new()
+ var.name = jaw_prop
+ var.type = "SINGLE_PROP"
+ var.targets[0].id = self.obj
+ var.targets[0].data_path = pb[ jaw_ctrl ].path_from_id() + '['+ '"' + jaw_prop + '"' + ']'
+
+
+ # Eyes driver
+ mch_eyes_parent = all_bones['mch']['eyes_parent'][0]
+
+ drv = pb[ mch_eyes_parent ].constraints[0].driver_add("influence").driver
+ drv.type='SUM'
+
+ var = drv.variables.new()
+ var.name = eyes_prop
+ var.type = "SINGLE_PROP"
+ var.targets[0].id = self.obj
+ var.targets[0].data_path = pb[ eyes_ctrl ].path_from_id() + '['+ '"' + eyes_prop + '"' + ']'
+
+ return jaw_prop, eyes_prop
+
+ def create_bones(self):
+ org_bones = self.org_bones
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Clear parents for org bones
+ for bone in [ bone for bone in org_bones if 'face' not in bone ]:
+ eb[bone].use_connect = False
+ eb[bone].parent = None
+
+ all_bones = {}
+
+ def_names = self.create_deformation()
+ ctrls, tweak_unique = self.all_controls()
+ mchs = self.create_mch(
+ ctrls['ctrls']['jaw'][0],
+ ctrls['ctrls']['tongue'][0]
+ )
+ return {
+ 'deform' : def_names,
+ 'ctrls' : ctrls['ctrls'],
+ 'tweaks' : ctrls['tweaks'],
+ 'mch' : mchs
+ }, tweak_unique
+
+
+ def generate(self):
+
+ all_bones, tweak_unique = self.create_bones()
+ self.parent_bones( all_bones, tweak_unique )
+ self.constraints( all_bones )
+ jaw_prop, eyes_prop = self.drivers_and_props( all_bones )
+
+
+ # Create UI
+ all_controls = []
+ all_controls += [ bone for bone in [ bgroup for bgroup in [ all_bones['ctrls'][group] for group in list( all_bones['ctrls'].keys() ) ] ] ]
+ all_controls += [ bone for bone in [ bgroup for bgroup in [ all_bones['tweaks'][group] for group in list( all_bones['tweaks'].keys() ) ] ] ]
+
+ all_ctrls = []
+ for group in all_controls:
+ for bone in group:
+ all_ctrls.append( bone )
+
+ controls_string = ", ".join(["'" + x + "'" for x in all_ctrls])
+ return [ script % (
+ controls_string,
+ all_bones['ctrls']['jaw'][0],
+ all_bones['ctrls']['eyes'][2],
+ jaw_prop,
+ eyes_prop )
+ ]
+
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+
+ #Setting up extra layers for the tweak bones
+ params.primary_layers_extra = bpy.props.BoolProperty(
+ name = "primary_layers_extra",
+ default = True,
+ description = ""
+ )
+ params.primary_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the 1st tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+ params.secondary_layers_extra = bpy.props.BoolProperty(
+ name = "secondary_layers_extra",
+ default = True,
+ description = ""
+ )
+ params.secondary_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the 2nd tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters."""
+ layers = ["primary_layers", "secondary_layers"]
+
+ for layer in layers:
+ r = layout.row()
+ r.prop( params, layer + "_extra" )
+ r.active = getattr( params, layer + "_extra" )
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+ for i in range(8):
+ row.prop(params, layer, index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+ for i in range(16,24):
+ row.prop(params, layer, index=i, toggle=True, text="")
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range(8,16):
+ row.prop(params, layer, index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+ for i in range(24,32):
+ row.prop(params, layer, index=i, toggle=True, text="")
+
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('face')
+ bone.head[:] = -0.0000, -0.0013, 0.0437
+ bone.tail[:] = -0.0000, -0.0013, 0.1048
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bones['face'] = bone.name
+ bone = arm.edit_bones.new('nose')
+ bone.head[:] = 0.0004, -0.0905, 0.1125
+ bone.tail[:] = 0.0004, -0.1105, 0.0864
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['nose'] = bone.name
+ bone = arm.edit_bones.new('lip.T.L')
+ bone.head[:] = 0.0000, -0.1022, 0.0563
+ bone.tail[:] = 0.0131, -0.0986, 0.0567
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lip.T.L'] = bone.name
+ bone = arm.edit_bones.new('lip.B.L')
+ bone.head[:] = 0.0000, -0.0993, 0.0455
+ bone.tail[:] = 0.0124, -0.0938, 0.0488
+ bone.roll = -0.0789
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lip.B.L'] = bone.name
+ bone = arm.edit_bones.new('jaw')
+ bone.head[:] = 0.0004, -0.0389, 0.0222
+ bone.tail[:] = 0.0004, -0.0923, 0.0044
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['jaw'] = bone.name
+ bone = arm.edit_bones.new('ear.L')
+ bone.head[:] = 0.0616, -0.0083, 0.0886
+ bone.tail[:] = 0.0663, -0.0101, 0.1151
+ bone.roll = -0.0324
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['ear.L'] = bone.name
+ bone = arm.edit_bones.new('ear.R')
+ bone.head[:] = -0.0616, -0.0083, 0.0886
+ bone.tail[:] = -0.0663, -0.0101, 0.1151
+ bone.roll = 0.0324
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['ear.R'] = bone.name
+ bone = arm.edit_bones.new('lip.T.R')
+ bone.head[:] = -0.0000, -0.1022, 0.0563
+ bone.tail[:] = -0.0131, -0.0986, 0.0567
+ bone.roll = -0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lip.T.R'] = bone.name
+ bone = arm.edit_bones.new('lip.B.R')
+ bone.head[:] = -0.0000, -0.0993, 0.0455
+ bone.tail[:] = -0.0124, -0.0938, 0.0488
+ bone.roll = 0.0789
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lip.B.R'] = bone.name
+ bone = arm.edit_bones.new('brow.B.L')
+ bone.head[:] = 0.0530, -0.0705, 0.1153
+ bone.tail[:] = 0.0472, -0.0780, 0.1192
+ bone.roll = 0.0412
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['brow.B.L'] = bone.name
+ bone = arm.edit_bones.new('lid.T.L')
+ bone.head[:] = 0.0515, -0.0692, 0.1104
+ bone.tail[:] = 0.0474, -0.0785, 0.1136
+ bone.roll = 0.1166
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lid.T.L'] = bone.name
+ bone = arm.edit_bones.new('brow.B.R')
+ bone.head[:] = -0.0530, -0.0705, 0.1153
+ bone.tail[:] = -0.0472, -0.0780, 0.1192
+ bone.roll = -0.0412
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['brow.B.R'] = bone.name
+ bone = arm.edit_bones.new('lid.T.R')
+ bone.head[:] = -0.0515, -0.0692, 0.1104
+ bone.tail[:] = -0.0474, -0.0785, 0.1136
+ bone.roll = -0.1166
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['lid.T.R'] = bone.name
+ bone = arm.edit_bones.new('forehead.L')
+ bone.head[:] = 0.0113, -0.0764, 0.1611
+ bone.tail[:] = 0.0144, -0.0912, 0.1236
+ bone.roll = 1.4313
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['forehead.L'] = bone.name
+ bone = arm.edit_bones.new('forehead.R')
+ bone.head[:] = -0.0113, -0.0764, 0.1611
+ bone.tail[:] = -0.0144, -0.0912, 0.1236
+ bone.roll = -1.4313
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['forehead.R'] = bone.name
+ bone = arm.edit_bones.new('eye.L')
+ bone.head[:] = 0.0360, -0.0686, 0.1107
+ bone.tail[:] = 0.0360, -0.0848, 0.1107
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['eye.L'] = bone.name
+ bone = arm.edit_bones.new('eye.R')
+ bone.head[:] = -0.0360, -0.0686, 0.1107
+ bone.tail[:] = -0.0360, -0.0848, 0.1107
+ bone.roll = -0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['eye.R'] = bone.name
+ bone = arm.edit_bones.new('cheek.T.L')
+ bone.head[:] = 0.0568, -0.0506, 0.1052
+ bone.tail[:] = 0.0379, -0.0834, 0.0816
+ bone.roll = -0.0096
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['cheek.T.L'] = bone.name
+ bone = arm.edit_bones.new('cheek.T.R')
+ bone.head[:] = -0.0568, -0.0506, 0.1052
+ bone.tail[:] = -0.0379, -0.0834, 0.0816
+ bone.roll = 0.0096
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['cheek.T.R'] = bone.name
+ bone = arm.edit_bones.new('teeth.T')
+ bone.head[:] = 0.0004, -0.0927, 0.0613
+ bone.tail[:] = 0.0004, -0.0621, 0.0613
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['teeth.T'] = bone.name
+ bone = arm.edit_bones.new('teeth.B')
+ bone.head[:] = 0.0004, -0.0881, 0.0397
+ bone.tail[:] = 0.0004, -0.0575, 0.0397
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['teeth.B'] = bone.name
+ bone = arm.edit_bones.new('tongue')
+ bone.head[:] = 0.0004, -0.0781, 0.0493
+ bone.tail[:] = 0.0004, -0.0620, 0.0567
+ bone.roll = 0.0000
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['face']]
+ bones['tongue'] = bone.name
+ bone = arm.edit_bones.new('nose.001')
+ bone.head[:] = 0.0004, -0.1105, 0.0864
+ bone.tail[:] = 0.0004, -0.1193, 0.0771
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose']]
+ bones['nose.001'] = bone.name
+ bone = arm.edit_bones.new('lip.T.L.001')
+ bone.head[:] = 0.0131, -0.0986, 0.0567
+ bone.tail[:] = 0.0236, -0.0877, 0.0519
+ bone.roll = 0.0236
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lip.T.L']]
+ bones['lip.T.L.001'] = bone.name
+ bone = arm.edit_bones.new('lip.B.L.001')
+ bone.head[:] = 0.0124, -0.0938, 0.0488
+ bone.tail[:] = 0.0236, -0.0877, 0.0519
+ bone.roll = 0.0731
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lip.B.L']]
+ bones['lip.B.L.001'] = bone.name
+ bone = arm.edit_bones.new('chin')
+ bone.head[:] = 0.0004, -0.0923, 0.0044
+ bone.tail[:] = 0.0004, -0.0921, 0.0158
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['jaw']]
+ bones['chin'] = bone.name
+ bone = arm.edit_bones.new('ear.L.001')
+ bone.head[:] = 0.0663, -0.0101, 0.1151
+ bone.tail[:] = 0.0804, 0.0065, 0.1189
+ bone.roll = 0.0656
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.L']]
+ bones['ear.L.001'] = bone.name
+ bone = arm.edit_bones.new('ear.R.001')
+ bone.head[:] = -0.0663, -0.0101, 0.1151
+ bone.tail[:] = -0.0804, 0.0065, 0.1189
+ bone.roll = -0.0656
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.R']]
+ bones['ear.R.001'] = bone.name
+ bone = arm.edit_bones.new('lip.T.R.001')
+ bone.head[:] = -0.0131, -0.0986, 0.0567
+ bone.tail[:] = -0.0236, -0.0877, 0.0519
+ bone.roll = -0.0236
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lip.T.R']]
+ bones['lip.T.R.001'] = bone.name
+ bone = arm.edit_bones.new('lip.B.R.001')
+ bone.head[:] = -0.0124, -0.0938, 0.0488
+ bone.tail[:] = -0.0236, -0.0877, 0.0519
+ bone.roll = -0.0731
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lip.B.R']]
+ bones['lip.B.R.001'] = bone.name
+ bone = arm.edit_bones.new('brow.B.L.001')
+ bone.head[:] = 0.0472, -0.0780, 0.1192
+ bone.tail[:] = 0.0387, -0.0832, 0.1202
+ bone.roll = 0.0192
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.L']]
+ bones['brow.B.L.001'] = bone.name
+ bone = arm.edit_bones.new('lid.T.L.001')
+ bone.head[:] = 0.0474, -0.0785, 0.1136
+ bone.tail[:] = 0.0394, -0.0838, 0.1147
+ bone.roll = 0.0791
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.L']]
+ bones['lid.T.L.001'] = bone.name
+ bone = arm.edit_bones.new('brow.B.R.001')
+ bone.head[:] = -0.0472, -0.0780, 0.1192
+ bone.tail[:] = -0.0387, -0.0832, 0.1202
+ bone.roll = -0.0192
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.R']]
+ bones['brow.B.R.001'] = bone.name
+ bone = arm.edit_bones.new('lid.T.R.001')
+ bone.head[:] = -0.0474, -0.0785, 0.1136
+ bone.tail[:] = -0.0394, -0.0838, 0.1147
+ bone.roll = -0.0791
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.R']]
+ bones['lid.T.R.001'] = bone.name
+ bone = arm.edit_bones.new('forehead.L.001')
+ bone.head[:] = 0.0321, -0.0663, 0.1646
+ bone.tail[:] = 0.0394, -0.0828, 0.1310
+ bone.roll = 0.9928
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.L']]
+ bones['forehead.L.001'] = bone.name
+ bone = arm.edit_bones.new('forehead.R.001')
+ bone.head[:] = -0.0321, -0.0663, 0.1646
+ bone.tail[:] = -0.0394, -0.0828, 0.1310
+ bone.roll = -0.9928
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.R']]
+ bones['forehead.R.001'] = bone.name
+ bone = arm.edit_bones.new('cheek.T.L.001')
+ bone.head[:] = 0.0379, -0.0834, 0.0816
+ bone.tail[:] = 0.0093, -0.0846, 0.1002
+ bone.roll = 0.0320
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.T.L']]
+ bones['cheek.T.L.001'] = bone.name
+ bone = arm.edit_bones.new('cheek.T.R.001')
+ bone.head[:] = -0.0379, -0.0834, 0.0816
+ bone.tail[:] = -0.0093, -0.0846, 0.1002
+ bone.roll = -0.0320
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.T.R']]
+ bones['cheek.T.R.001'] = bone.name
+ bone = arm.edit_bones.new('tongue.001')
+ bone.head[:] = 0.0004, -0.0620, 0.0567
+ bone.tail[:] = 0.0004, -0.0406, 0.0584
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['tongue']]
+ bones['tongue.001'] = bone.name
+ bone = arm.edit_bones.new('nose.002')
+ bone.head[:] = 0.0004, -0.1193, 0.0771
+ bone.tail[:] = 0.0004, -0.1118, 0.0739
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose.001']]
+ bones['nose.002'] = bone.name
+ bone = arm.edit_bones.new('chin.001')
+ bone.head[:] = 0.0004, -0.0921, 0.0158
+ bone.tail[:] = 0.0004, -0.0914, 0.0404
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['chin']]
+ bones['chin.001'] = bone.name
+ bone = arm.edit_bones.new('ear.L.002')
+ bone.head[:] = 0.0804, 0.0065, 0.1189
+ bone.tail[:] = 0.0808, 0.0056, 0.0935
+ bone.roll = -0.0265
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.L.001']]
+ bones['ear.L.002'] = bone.name
+ bone = arm.edit_bones.new('ear.R.002')
+ bone.head[:] = -0.0804, 0.0065, 0.1189
+ bone.tail[:] = -0.0808, 0.0056, 0.0935
+ bone.roll = 0.0265
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.R.001']]
+ bones['ear.R.002'] = bone.name
+ bone = arm.edit_bones.new('brow.B.L.002')
+ bone.head[:] = 0.0387, -0.0832, 0.1202
+ bone.tail[:] = 0.0295, -0.0826, 0.1179
+ bone.roll = -0.0278
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.L.001']]
+ bones['brow.B.L.002'] = bone.name
+ bone = arm.edit_bones.new('lid.T.L.002')
+ bone.head[:] = 0.0394, -0.0838, 0.1147
+ bone.tail[:] = 0.0317, -0.0832, 0.1131
+ bone.roll = -0.0356
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.L.001']]
+ bones['lid.T.L.002'] = bone.name
+ bone = arm.edit_bones.new('brow.B.R.002')
+ bone.head[:] = -0.0387, -0.0832, 0.1202
+ bone.tail[:] = -0.0295, -0.0826, 0.1179
+ bone.roll = 0.0278
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.R.001']]
+ bones['brow.B.R.002'] = bone.name
+ bone = arm.edit_bones.new('lid.T.R.002')
+ bone.head[:] = -0.0394, -0.0838, 0.1147
+ bone.tail[:] = -0.0317, -0.0832, 0.1131
+ bone.roll = 0.0356
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.R.001']]
+ bones['lid.T.R.002'] = bone.name
+ bone = arm.edit_bones.new('forehead.L.002')
+ bone.head[:] = 0.0482, -0.0506, 0.1620
+ bone.tail[:] = 0.0556, -0.0689, 0.1249
+ bone.roll = 0.4509
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.L.001']]
+ bones['forehead.L.002'] = bone.name
+ bone = arm.edit_bones.new('forehead.R.002')
+ bone.head[:] = -0.0482, -0.0506, 0.1620
+ bone.tail[:] = -0.0556, -0.0689, 0.1249
+ bone.roll = -0.4509
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.R.001']]
+ bones['forehead.R.002'] = bone.name
+ bone = arm.edit_bones.new('nose.L')
+ bone.head[:] = 0.0093, -0.0846, 0.1002
+ bone.tail[:] = 0.0118, -0.0966, 0.0757
+ bone.roll = -0.0909
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.T.L.001']]
+ bones['nose.L'] = bone.name
+ bone = arm.edit_bones.new('nose.R')
+ bone.head[:] = -0.0093, -0.0846, 0.1002
+ bone.tail[:] = -0.0118, -0.0966, 0.0757
+ bone.roll = 0.0909
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.T.R.001']]
+ bones['nose.R'] = bone.name
+ bone = arm.edit_bones.new('tongue.002')
+ bone.head[:] = 0.0004, -0.0406, 0.0584
+ bone.tail[:] = 0.0004, -0.0178, 0.0464
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['tongue.001']]
+ bones['tongue.002'] = bone.name
+ bone = arm.edit_bones.new('nose.003')
+ bone.head[:] = 0.0004, -0.1118, 0.0739
+ bone.tail[:] = 0.0004, -0.1019, 0.0733
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose.002']]
+ bones['nose.003'] = bone.name
+ bone = arm.edit_bones.new('ear.L.003')
+ bone.head[:] = 0.0808, 0.0056, 0.0935
+ bone.tail[:] = 0.0677, -0.0109, 0.0752
+ bone.roll = 0.3033
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.L.002']]
+ bones['ear.L.003'] = bone.name
+ bone = arm.edit_bones.new('ear.R.003')
+ bone.head[:] = -0.0808, 0.0056, 0.0935
+ bone.tail[:] = -0.0677, -0.0109, 0.0752
+ bone.roll = -0.3033
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.R.002']]
+ bones['ear.R.003'] = bone.name
+ bone = arm.edit_bones.new('brow.B.L.003')
+ bone.head[:] = 0.0295, -0.0826, 0.1179
+ bone.tail[:] = 0.0201, -0.0812, 0.1095
+ bone.roll = 0.0417
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.L.002']]
+ bones['brow.B.L.003'] = bone.name
+ bone = arm.edit_bones.new('lid.T.L.003')
+ bone.head[:] = 0.0317, -0.0832, 0.1131
+ bone.tail[:] = 0.0237, -0.0826, 0.1058
+ bone.roll = 0.0245
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.L.002']]
+ bones['lid.T.L.003'] = bone.name
+ bone = arm.edit_bones.new('brow.B.R.003')
+ bone.head[:] = -0.0295, -0.0826, 0.1179
+ bone.tail[:] = -0.0201, -0.0812, 0.1095
+ bone.roll = -0.0417
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.B.R.002']]
+ bones['brow.B.R.003'] = bone.name
+ bone = arm.edit_bones.new('lid.T.R.003')
+ bone.head[:] = -0.0317, -0.0832, 0.1131
+ bone.tail[:] = -0.0237, -0.0826, 0.1058
+ bone.roll = -0.0245
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.R.002']]
+ bones['lid.T.R.003'] = bone.name
+ bone = arm.edit_bones.new('temple.L')
+ bone.head[:] = 0.0585, -0.0276, 0.1490
+ bone.tail[:] = 0.0607, -0.0295, 0.0962
+ bone.roll = -0.0650
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.L.002']]
+ bones['temple.L'] = bone.name
+ bone = arm.edit_bones.new('temple.R')
+ bone.head[:] = -0.0585, -0.0276, 0.1490
+ bone.tail[:] = -0.0607, -0.0295, 0.0962
+ bone.roll = 0.0650
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['forehead.R.002']]
+ bones['temple.R'] = bone.name
+ bone = arm.edit_bones.new('nose.L.001')
+ bone.head[:] = 0.0118, -0.0966, 0.0757
+ bone.tail[:] = 0.0004, -0.1193, 0.0771
+ bone.roll = 0.1070
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose.L']]
+ bones['nose.L.001'] = bone.name
+ bone = arm.edit_bones.new('nose.R.001')
+ bone.head[:] = -0.0118, -0.0966, 0.0757
+ bone.tail[:] = -0.0004, -0.1193, 0.0771
+ bone.roll = -0.1070
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose.R']]
+ bones['nose.R.001'] = bone.name
+ bone = arm.edit_bones.new('nose.004')
+ bone.head[:] = 0.0004, -0.1019, 0.0733
+ bone.tail[:] = 0.0004, -0.1014, 0.0633
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['nose.003']]
+ bones['nose.004'] = bone.name
+ bone = arm.edit_bones.new('ear.L.004')
+ bone.head[:] = 0.0677, -0.0109, 0.0752
+ bone.tail[:] = 0.0616, -0.0083, 0.0886
+ bone.roll = 0.1518
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.L.003']]
+ bones['ear.L.004'] = bone.name
+ bone = arm.edit_bones.new('ear.R.004')
+ bone.head[:] = -0.0677, -0.0109, 0.0752
+ bone.tail[:] = -0.0616, -0.0083, 0.0886
+ bone.roll = -0.1518
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['ear.R.003']]
+ bones['ear.R.004'] = bone.name
+ bone = arm.edit_bones.new('lid.B.L')
+ bone.head[:] = 0.0237, -0.0826, 0.1058
+ bone.tail[:] = 0.0319, -0.0831, 0.1050
+ bone.roll = -0.1108
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.L.003']]
+ bones['lid.B.L'] = bone.name
+ bone = arm.edit_bones.new('lid.B.R')
+ bone.head[:] = -0.0237, -0.0826, 0.1058
+ bone.tail[:] = -0.0319, -0.0831, 0.1050
+ bone.roll = 0.1108
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.T.R.003']]
+ bones['lid.B.R'] = bone.name
+ bone = arm.edit_bones.new('jaw.L')
+ bone.head[:] = 0.0607, -0.0295, 0.0962
+ bone.tail[:] = 0.0451, -0.0338, 0.0533
+ bone.roll = 0.0871
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['temple.L']]
+ bones['jaw.L'] = bone.name
+ bone = arm.edit_bones.new('jaw.R')
+ bone.head[:] = -0.0607, -0.0295, 0.0962
+ bone.tail[:] = -0.0451, -0.0338, 0.0533
+ bone.roll = -0.0871
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['temple.R']]
+ bones['jaw.R'] = bone.name
+ bone = arm.edit_bones.new('lid.B.L.001')
+ bone.head[:] = 0.0319, -0.0831, 0.1050
+ bone.tail[:] = 0.0389, -0.0826, 0.1050
+ bone.roll = -0.0207
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.L']]
+ bones['lid.B.L.001'] = bone.name
+ bone = arm.edit_bones.new('lid.B.R.001')
+ bone.head[:] = -0.0319, -0.0831, 0.1050
+ bone.tail[:] = -0.0389, -0.0826, 0.1050
+ bone.roll = 0.0207
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.R']]
+ bones['lid.B.R.001'] = bone.name
+ bone = arm.edit_bones.new('jaw.L.001')
+ bone.head[:] = 0.0451, -0.0338, 0.0533
+ bone.tail[:] = 0.0166, -0.0758, 0.0187
+ bone.roll = 0.0458
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['jaw.L']]
+ bones['jaw.L.001'] = bone.name
+ bone = arm.edit_bones.new('jaw.R.001')
+ bone.head[:] = -0.0451, -0.0338, 0.0533
+ bone.tail[:] = -0.0166, -0.0758, 0.0187
+ bone.roll = -0.0458
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['jaw.R']]
+ bones['jaw.R.001'] = bone.name
+ bone = arm.edit_bones.new('lid.B.L.002')
+ bone.head[:] = 0.0389, -0.0826, 0.1050
+ bone.tail[:] = 0.0472, -0.0781, 0.1068
+ bone.roll = 0.0229
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.L.001']]
+ bones['lid.B.L.002'] = bone.name
+ bone = arm.edit_bones.new('lid.B.R.002')
+ bone.head[:] = -0.0389, -0.0826, 0.1050
+ bone.tail[:] = -0.0472, -0.0781, 0.1068
+ bone.roll = -0.0229
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.R.001']]
+ bones['lid.B.R.002'] = bone.name
+ bone = arm.edit_bones.new('chin.L')
+ bone.head[:] = 0.0166, -0.0758, 0.0187
+ bone.tail[:] = 0.0236, -0.0877, 0.0519
+ bone.roll = 0.1513
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['jaw.L.001']]
+ bones['chin.L'] = bone.name
+ bone = arm.edit_bones.new('chin.R')
+ bone.head[:] = -0.0166, -0.0758, 0.0187
+ bone.tail[:] = -0.0236, -0.0877, 0.0519
+ bone.roll = -0.1513
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['jaw.R.001']]
+ bones['chin.R'] = bone.name
+ bone = arm.edit_bones.new('lid.B.L.003')
+ bone.head[:] = 0.0472, -0.0781, 0.1068
+ bone.tail[:] = 0.0515, -0.0692, 0.1104
+ bone.roll = -0.0147
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.L.002']]
+ bones['lid.B.L.003'] = bone.name
+ bone = arm.edit_bones.new('lid.B.R.003')
+ bone.head[:] = -0.0472, -0.0781, 0.1068
+ bone.tail[:] = -0.0515, -0.0692, 0.1104
+ bone.roll = 0.0147
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['lid.B.R.002']]
+ bones['lid.B.R.003'] = bone.name
+ bone = arm.edit_bones.new('cheek.B.L')
+ bone.head[:] = 0.0236, -0.0877, 0.0519
+ bone.tail[:] = 0.0493, -0.0691, 0.0632
+ bone.roll = 0.0015
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['chin.L']]
+ bones['cheek.B.L'] = bone.name
+ bone = arm.edit_bones.new('cheek.B.R')
+ bone.head[:] = -0.0236, -0.0877, 0.0519
+ bone.tail[:] = -0.0493, -0.0691, 0.0632
+ bone.roll = -0.0015
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['chin.R']]
+ bones['cheek.B.R'] = bone.name
+ bone = arm.edit_bones.new('cheek.B.L.001')
+ bone.head[:] = 0.0493, -0.0691, 0.0632
+ bone.tail[:] = 0.0568, -0.0506, 0.1052
+ bone.roll = -0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.B.L']]
+ bones['cheek.B.L.001'] = bone.name
+ bone = arm.edit_bones.new('cheek.B.R.001')
+ bone.head[:] = -0.0493, -0.0691, 0.0632
+ bone.tail[:] = -0.0568, -0.0506, 0.1052
+ bone.roll = 0.0000
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.B.R']]
+ bones['cheek.B.R.001'] = bone.name
+ bone = arm.edit_bones.new('brow.T.L')
+ bone.head[:] = 0.0568, -0.0506, 0.1052
+ bone.tail[:] = 0.0556, -0.0689, 0.1249
+ bone.roll = 0.1990
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.B.L.001']]
+ bones['brow.T.L'] = bone.name
+ bone = arm.edit_bones.new('brow.T.R')
+ bone.head[:] = -0.0568, -0.0506, 0.1052
+ bone.tail[:] = -0.0556, -0.0689, 0.1249
+ bone.roll = -0.1990
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['cheek.B.R.001']]
+ bones['brow.T.R'] = bone.name
+ bone = arm.edit_bones.new('brow.T.L.001')
+ bone.head[:] = 0.0556, -0.0689, 0.1249
+ bone.tail[:] = 0.0394, -0.0828, 0.1310
+ bone.roll = 0.2372
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.L']]
+ bones['brow.T.L.001'] = bone.name
+ bone = arm.edit_bones.new('brow.T.R.001')
+ bone.head[:] = -0.0556, -0.0689, 0.1249
+ bone.tail[:] = -0.0394, -0.0828, 0.1310
+ bone.roll = -0.2372
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.R']]
+ bones['brow.T.R.001'] = bone.name
+ bone = arm.edit_bones.new('brow.T.L.002')
+ bone.head[:] = 0.0394, -0.0828, 0.1310
+ bone.tail[:] = 0.0144, -0.0912, 0.1236
+ bone.roll = 0.0724
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.L.001']]
+ bones['brow.T.L.002'] = bone.name
+ bone = arm.edit_bones.new('brow.T.R.002')
+ bone.head[:] = -0.0394, -0.0828, 0.1310
+ bone.tail[:] = -0.0144, -0.0912, 0.1236
+ bone.roll = -0.0724
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.R.001']]
+ bones['brow.T.R.002'] = bone.name
+ bone = arm.edit_bones.new('brow.T.L.003')
+ bone.head[:] = 0.0144, -0.0912, 0.1236
+ bone.tail[:] = 0.0003, -0.0905, 0.1125
+ bone.roll = -0.0423
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.L.002']]
+ bones['brow.T.L.003'] = bone.name
+ bone = arm.edit_bones.new('brow.T.R.003')
+ bone.head[:] = -0.0144, -0.0912, 0.1236
+ bone.tail[:] = -0.0003, -0.0905, 0.1125
+ bone.roll = 0.0423
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['brow.T.R.002']]
+ bones['brow.T.R.003'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['face']]
+ pbone.rigify_type = 'pitchipoy.super_face'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.T.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.B.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['jaw']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.T.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.B.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['eye.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['eye.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.T.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.T.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['teeth.T']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['teeth.B']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['tongue']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.T.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.B.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['chin']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.T.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lip.B.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.T.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.T.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['tongue.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['chin.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['forehead.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['tongue.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.L.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.R.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.L.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.L.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.B.R.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.T.R.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['temple.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['temple.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['nose.004']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.L.004']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['ear.R.004']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['jaw.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['jaw.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['jaw.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['jaw.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['chin.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['chin.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.L.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['lid.B.R.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.B.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.B.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.B.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['cheek.B.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.R']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.L.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.R.001']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.L.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.R.002']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.L.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['brow.T.R.003']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
+
+def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [
+ ( 0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ),
+ ( -0.5 * size, -2.9802322387695312e-08 * size, 0.5 * size ),
+ ( 0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ),
+ ( -0.5 * size, 2.9802322387695312e-08 * size, -0.5 * size ),
+ ]
+
+ edges = [(0, 1), (2, 3), (0, 2), (3, 1) ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ mesh.update()
+ return obj
+ else:
+ return None
+
diff --git a/rigify/rigs/pitchipoy/super_finger.py b/rigify/rigs/pitchipoy/super_finger.py
new file mode 100644
index 00000000..3b39c770
--- /dev/null
+++ b/rigify/rigs/pitchipoy/super_finger.py
@@ -0,0 +1,414 @@
+import bpy
+from mathutils import Vector
+from ...utils import copy_bone, flip_bone
+from ...utils import strip_org, make_deformer_name, connected_children_names, make_mechanism_name
+from ...utils import create_circle_widget, create_sphere_widget, create_widget
+from ...utils import MetarigError
+from rna_prop_ui import rna_idprop_ui_prop_get
+
+script = """
+controls = [%s]
+master_name = '%s'
+if is_selected(controls):
+ layout.prop(pose_bones[master_name], '["%s"]', text="Curvature", slider=True)
+"""
+
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ self.obj = obj
+ self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
+ self.params = params
+
+ if len(self.org_bones) <= 1:
+ raise MetarigError("RIGIFY ERROR: Bone '%s': listen bro, that finger rig jusaint put tugetha rite. A little hint, use more than one bone!!" % (strip_org(bone_name)))
+
+
+ def generate(self):
+ org_bones = self.org_bones
+
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Bone name lists
+ ctrl_chain = []
+ def_chain = []
+ mch_chain = []
+ mch_drv_chain = []
+
+ # Create ctrl master bone
+ org_name = self.org_bones[0]
+ temp_name = strip_org(self.org_bones[0])
+
+ suffix = temp_name[-2:]
+ master_name = temp_name[:-5] + "_master" + suffix
+ master_name = copy_bone( self.obj, org_name, master_name )
+ ctrl_bone_master = eb[ master_name ]
+
+ ## Parenting bug fix ??
+ ctrl_bone_master.use_connect = False
+ ctrl_bone_master.parent = None
+
+ ctrl_bone_master.tail += ( eb[ org_bones[-1] ].tail - eb[org_name].head ) * 1.25
+
+ for bone in org_bones:
+ eb[bone].use_connect = False
+ if org_bones.index( bone ) != 0:
+ eb[bone].parent = None
+
+ # Creating the bone chains
+ for i in range(len(self.org_bones)):
+
+ name = self.org_bones[i]
+ ctrl_name = strip_org(name)
+
+ # Create control bones
+ ctrl_bone = copy_bone( self.obj, name, ctrl_name )
+ ctrl_bone_e = eb[ ctrl_name ]
+
+ # Create deformation bones
+ def_name = make_deformer_name( ctrl_name )
+ def_bone = copy_bone( self.obj, name, def_name )
+
+ # Create mechanism bones
+ mch_name = make_mechanism_name( ctrl_name )
+ mch_bone = copy_bone( self.obj, name, mch_name )
+
+ # Create mechanism driver bones
+ drv_name = make_mechanism_name(ctrl_name) + "_drv"
+ mch_bone_drv = copy_bone(self.obj, name, drv_name)
+ mch_bone_drv_e = eb[drv_name]
+
+ # Adding to lists
+ ctrl_chain += [ctrl_name]
+ def_chain += [def_bone]
+ mch_chain += [mch_bone]
+ mch_drv_chain += [drv_name]
+
+ # Restoring org chain parenting
+ for bone in org_bones[1:]:
+ eb[bone].parent = eb[ org_bones[ org_bones.index(bone) - 1 ] ]
+
+ # Parenting the master bone to the first org
+ ctrl_bone_master = eb[ master_name ]
+ ctrl_bone_master.parent = eb[ org_bones[0] ]
+
+ # Parenting chain bones
+ for i in range(len(self.org_bones)):
+ # Edit bone references
+ def_bone_e = eb[def_chain[i]]
+ ctrl_bone_e = eb[ctrl_chain[i]]
+ mch_bone_e = eb[mch_chain[i]]
+ mch_bone_drv_e = eb[mch_drv_chain[i]]
+
+ if i == 0:
+ # First ctl bone
+ ctrl_bone_e.parent = mch_bone_drv_e
+ ctrl_bone_e.use_connect = False
+ # First def bone
+ def_bone_e.parent = eb[self.org_bones[i]].parent
+ def_bone_e.use_connect = False
+ # First mch bone
+ mch_bone_e.parent = eb[self.org_bones[i]].parent
+ mch_bone_e.use_connect = False
+ # First mch driver bone
+ mch_bone_drv_e.parent = eb[self.org_bones[i]].parent
+ mch_bone_drv_e.use_connect = False
+ else:
+ # The rest
+ ctrl_bone_e.parent = mch_bone_drv_e
+ ctrl_bone_e.use_connect = False
+
+ def_bone_e.parent = eb[def_chain[i-1]]
+ def_bone_e.use_connect = True
+
+ mch_bone_drv_e.parent = eb[ctrl_chain[i-1]]
+ mch_bone_drv_e.use_connect = False
+
+ # Parenting mch bone
+ mch_bone_e.parent = ctrl_bone_e
+ mch_bone_e.use_connect = False
+
+ # Creating tip conrtol bone
+ tip_name = copy_bone( self.obj, org_bones[-1], temp_name )
+ ctrl_bone_tip = eb[ tip_name ]
+ flip_bone( self.obj, tip_name )
+ ctrl_bone_tip.length /= 2
+
+ ctrl_bone_tip.parent = eb[ctrl_chain[-1]]
+
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ pb = self.obj.pose.bones
+
+ # Setting pose bones locks
+ pb_master = pb[master_name]
+ pb_master.lock_scale = True,False,True
+
+ pb[tip_name].lock_scale = True,True,True
+ pb[tip_name].lock_rotation = True,True,True
+ pb[tip_name].lock_rotation_w = True
+
+ pb_master['finger_curve'] = 0.0
+ prop = rna_idprop_ui_prop_get(pb_master, 'finger_curve')
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["description"] = "Rubber hose finger cartoon effect"
+
+ # Pose settings
+ for org, ctrl, deform, mch, mch_drv in zip(self.org_bones, ctrl_chain, def_chain, mch_chain, mch_drv_chain):
+
+ # Constraining the org bones
+ #con = pb[org].constraints.new('COPY_TRANSFORMS')
+ #con.target = self.obj
+ #con.subtarget = ctrl
+
+ # Constraining the deform bones
+ con = pb[deform].constraints.new('COPY_TRANSFORMS')
+ con.target = self.obj
+ con.subtarget = mch
+
+ # Constraining the mch bones
+ if mch_chain.index(mch) == 0:
+ con = pb[mch].constraints.new('COPY_LOCATION')
+ con.target = self.obj
+ con.subtarget = ctrl
+
+ con = pb[mch].constraints.new('COPY_SCALE')
+ con.target = self.obj
+ con.subtarget = ctrl
+
+ con = pb[mch].constraints.new('DAMPED_TRACK')
+ con.target = self.obj
+ con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1]
+
+ con = pb[mch].constraints.new('STRETCH_TO')
+ con.target = self.obj
+ con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1]
+ con.volume = 'NO_VOLUME'
+
+ elif mch_chain.index(mch) == len(mch_chain) - 1:
+ con = pb[mch].constraints.new('DAMPED_TRACK')
+ con.target = self.obj
+ con.subtarget = tip_name
+
+ con = pb[mch].constraints.new('STRETCH_TO')
+ con.target = self.obj
+ con.subtarget = tip_name
+ con.volume = 'NO_VOLUME'
+ else:
+ con = pb[mch].constraints.new('DAMPED_TRACK')
+ con.target = self.obj
+ con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1]
+
+ con = pb[mch].constraints.new('STRETCH_TO')
+ con.target = self.obj
+ con.subtarget = ctrl_chain[ctrl_chain.index(ctrl)+1]
+ con.volume = 'NO_VOLUME'
+
+ # Constraining and driving mch driver bones
+ pb[mch_drv].rotation_mode = 'YZX'
+
+ if mch_drv_chain.index(mch_drv) == 0:
+ # Constraining to master bone
+ con = pb[mch_drv].constraints.new('COPY_LOCATION')
+ con.target = self.obj
+ con.subtarget = master_name
+
+ con = pb[mch_drv].constraints.new('COPY_ROTATION')
+ con.target = self.obj
+ con.subtarget = master_name
+ con.target_space = 'LOCAL'
+ con.owner_space = 'LOCAL'
+
+ else:
+ # Match axis to expression
+ options = {
+ "X" : { "axis" : 0,
+ "expr" : '(1-sy)*pi' },
+ "-X" : { "axis" : 0,
+ "expr" : '-((1-sy)*pi)' },
+ "Y" : { "axis" : 1,
+ "expr" : '(1-sy)*pi' },
+ "-Y" : { "axis" : 1,
+ "expr" : '-((1-sy)*pi)' },
+ "Z" : { "axis" : 2,
+ "expr" : '(1-sy)*pi' },
+ "-Z" : { "axis" : 2,
+ "expr" : '-((1-sy)*pi)' }
+ }
+
+ axis = self.params.primary_rotation_axis
+
+ # Drivers
+ drv = pb[mch_drv].driver_add("rotation_euler", options[axis]["axis"]).driver
+ drv.type = 'SCRIPTED'
+ drv.expression = options[axis]["expr"]
+ drv_var = drv.variables.new()
+ drv_var.name = 'sy'
+ drv_var.type = "SINGLE_PROP"
+ drv_var.targets[0].id = self.obj
+ drv_var.targets[0].data_path = pb[master_name].path_from_id() + '.scale.y'
+
+ # Setting bone curvature setting, costum property, and drivers
+ def_bone = self.obj.data.bones[deform]
+
+ def_bone.bbone_segments = 8
+ drv = def_bone.driver_add("bbone_in").driver # Ease in
+
+ drv.type='SUM'
+ drv_var = drv.variables.new()
+ drv_var.name = "curvature"
+ drv_var.type = "SINGLE_PROP"
+ drv_var.targets[0].id = self.obj
+ drv_var.targets[0].data_path = pb_master.path_from_id() + '["finger_curve"]'
+
+ drv = def_bone.driver_add("bbone_out").driver # Ease out
+
+ drv.type='SUM'
+ drv_var = drv.variables.new()
+ drv_var.name = "curvature"
+ drv_var.type = "SINGLE_PROP"
+ drv_var.targets[0].id = self.obj
+ drv_var.targets[0].data_path = pb_master.path_from_id() + '["finger_curve"]'
+
+
+ # Assigning shapes to control bones
+ create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5)
+
+ # Create ctrl master widget
+ w = create_widget(self.obj, master_name)
+ if w != None:
+ mesh = w.data
+ verts = [(0, 0, 0), (0, 1, 0), (0.05, 1, 0), (0.05, 1.1, 0), (-0.05, 1.1, 0), (-0.05, 1, 0)]
+ if 'Z' in self.params.primary_rotation_axis:
+ # Flip x/z coordinates
+ temp = []
+ for v in verts:
+ temp += [(v[2], v[1], v[0])]
+ verts = temp
+ edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 1)]
+ mesh.from_pydata(verts, edges, [])
+ mesh.update()
+
+ # Create tip control widget
+ create_circle_widget(self.obj, tip_name, radius=0.3, head_tail=0.0)
+
+ # Create UI
+ controls_string = ", ".join(
+ ["'" + x + "'" for x in ctrl_chain]
+ ) + ", " + "'" + master_name + "'"
+ return [script % (controls_string, master_name, 'finger_curve')]
+
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+ items = [('X', 'X', ''), ('Y', 'Y', ''), ('Z', 'Z', ''), ('-X', '-X', ''), ('-Y', '-Y', ''), ('-Z', '-Z', '')]
+ params.primary_rotation_axis = bpy.props.EnumProperty(items=items, name="Primary Rotation Axis", default='X')
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters.
+ """
+ r = layout.row()
+ r.label(text="Bend rotation axis:")
+ r.prop(params, "primary_rotation_axis", text="")
+
+
+def create_sample(obj):
+ # generated by rigify.utils.write_metarig
+ bpy.ops.object.mode_set(mode='EDIT')
+ arm = obj.data
+
+ bones = {}
+
+ bone = arm.edit_bones.new('palm.04.L')
+ bone.head[:] = 0.0043, -0.0030, -0.0026
+ bone.tail[:] = 0.0642, 0.0037, -0.0469
+ bone.roll = -2.5155
+ bone.use_connect = False
+ bones['palm.04.L'] = bone.name
+ bone = arm.edit_bones.new('f_pinky.01.L')
+ bone.head[:] = 0.0642, 0.0037, -0.0469
+ bone.tail[:] = 0.0703, 0.0039, -0.0741
+ bone.roll = -1.9749
+ bone.use_connect = False
+ bone.parent = arm.edit_bones[bones['palm.04.L']]
+ bones['f_pinky.01.L'] = bone.name
+ bone = arm.edit_bones.new('f_pinky.02.L')
+ bone.head[:] = 0.0703, 0.0039, -0.0741
+ bone.tail[:] = 0.0732, 0.0044, -0.0965
+ bone.roll = -1.9059
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['f_pinky.01.L']]
+ bones['f_pinky.02.L'] = bone.name
+ bone = arm.edit_bones.new('f_pinky.03.L')
+ bone.head[:] = 0.0732, 0.0044, -0.0965
+ bone.tail[:] = 0.0725, 0.0046, -0.1115
+ bone.roll = -1.7639
+ bone.use_connect = True
+ bone.parent = arm.edit_bones[bones['f_pinky.02.L']]
+ bones['f_pinky.03.L'] = bone.name
+
+ bpy.ops.object.mode_set(mode='OBJECT')
+ pbone = obj.pose.bones[bones['palm.04.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'YXZ'
+ pbone = obj.pose.bones[bones['f_pinky.01.L']]
+ pbone.rigify_type = 'pitchipoy.simple_tentacle'
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ try:
+ pbone.rigify_parameters.separate_extra_layers = True
+ except AttributeError:
+ pass
+ try:
+ pbone.rigify_parameters.extra_layers = [False, False, False, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
+ except AttributeError:
+ pass
+ try:
+ pbone.rigify_parameters.tweak_extra_layers = False
+ except AttributeError:
+ pass
+ pbone = obj.pose.bones[bones['f_pinky.02.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+ pbone = obj.pose.bones[bones['f_pinky.03.L']]
+ pbone.rigify_type = ''
+ pbone.lock_location = (False, False, False)
+ pbone.lock_rotation = (False, False, False)
+ pbone.lock_rotation_w = False
+ pbone.lock_scale = (False, False, False)
+ pbone.rotation_mode = 'QUATERNION'
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ for bone in arm.edit_bones:
+ bone.select = False
+ bone.select_head = False
+ bone.select_tail = False
+ for b in bones:
+ bone = arm.edit_bones[bones[b]]
+ bone.select = True
+ bone.select_head = True
+ bone.select_tail = True
+ arm.edit_bones.active = bone
+
+
+
+
+
diff --git a/rigify/rigs/pitchipoy/super_torso_turbo.py b/rigify/rigs/pitchipoy/super_torso_turbo.py
new file mode 100644
index 00000000..c676d592
--- /dev/null
+++ b/rigify/rigs/pitchipoy/super_torso_turbo.py
@@ -0,0 +1,901 @@
+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
+ 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 ],
+ })
+
+
+ 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/super_widgets.py b/rigify/rigs/pitchipoy/super_widgets.py
new file mode 100644
index 00000000..8f3eba5b
--- /dev/null
+++ b/rigify/rigs/pitchipoy/super_widgets.py
@@ -0,0 +1,164 @@
+import bpy
+import imp
+import importlib
+from ...utils import create_widget
+
+WGT_LAYERS = [x == 19 for x in range(0, 20)] # Widgets go on the last scene layer.
+MODULE_NAME = "super_widgets" # Windows/Mac blender is weird, so __package__ doesn't work
+
+
+def create_eye_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(1.1920928955078125e-07*size, 0.5000000596046448*size, 0.0*size), (-0.12940943241119385*size, 0.482962965965271*size, 0.0*size), (-0.24999988079071045*size, 0.4330127537250519*size, 0.0*size), (-0.35355329513549805*size, 0.35355344414711*size, 0.0*size), (-0.43301260471343994*size, 0.2500000596046448*size, 0.0*size), (-0.4829627275466919*size, 0.12940959632396698*size, 0.0*size), (-0.49999988079071045*size, 1.0094120739267964e-07*size, 0.0*size), (-0.482962965965271*size, -0.12940940260887146*size, 0.0*size), (-0.43301260471343994*size, -0.24999986588954926*size, 0.0*size), (-0.3535534143447876*size, -0.35355323553085327*size, 0.0*size), (-0.25*size, -0.43301257491111755*size, 0.0*size), (-0.1294095516204834*size, -0.48296281695365906*size, 0.0*size), (-1.1920928955078125e-07*size, -0.4999999403953552*size, 0.0*size), (0.12940943241119385*size, -0.4829629063606262*size, 0.0*size), (0.24999988079071045*size, -0.4330127537250519*size, 0.0*size), (0.35355329513549805*size, -0.35355353355407715*size, 0.0*size), (0.4330127239227295*size, -0.25000008940696716*size, 0.0*size), (0.482962965965271*size, -0.12940965592861176*size, 0.0*size), (0.5000001192092896*size, -1.6926388468618825e-07*size, 0.0*size), (0.48296308517456055*size, 0.1294093281030655*size, 0.0*size), (0.4330129623413086*size, 0.24999980628490448*size, 0.0*size), (0.35355377197265625*size, 0.35355323553085327*size, 0.0*size), (0.25000035762786865*size, 0.43301260471343994*size, 0.0*size), (0.1294100284576416*size, 0.48296287655830383*size, 0.0*size), ]
+ edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_eyes_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(0.8928930759429932*size, -0.7071065902709961*size, 0.0*size), (0.8928932547569275*size, 0.7071067690849304*size, 0.0*size), (-1.8588197231292725*size, -0.9659252762794495*size, 0.0*size), (-2.100001096725464*size, -0.8660248517990112*size, 0.0*size), (-2.3071072101593018*size, -0.7071059942245483*size, 0.0*size), (-2.4660258293151855*size, -0.49999913573265076*size, 0.0*size), (-2.5659260749816895*size, -0.258818119764328*size, 0.0*size), (-2.5999999046325684*size, 8.575012770961621e-07*size, 0.0*size), (-2.5659255981445312*size, 0.2588198482990265*size, 0.0*size), (-2.4660253524780273*size, 0.5000006556510925*size, 0.0*size), (-2.3071064949035645*size, 0.7071075439453125*size, 0.0*size), (-2.099999189376831*size, 0.866025984287262*size, 0.0*size), (-1.8588184118270874*size, 0.9659261703491211*size, 0.0*size), (-1.5999996662139893*size, 1.000000238418579*size, 0.0*size), (-1.341180443763733*size, 0.9659258723258972*size, 0.0*size), (-1.0999995470046997*size, 0.8660253882408142*size, 0.0*size), (-0.8928929567337036*size, 0.7071067094802856*size, 0.0*size), (-0.892893373966217*size, -0.7071066498756409*size, 0.0*size), (-1.100000262260437*size, -0.8660252690315247*size, 0.0*size), (-1.3411810398101807*size, -0.9659255743026733*size, 0.0*size), (1.600000023841858*size, 1.0*size, 0.0*size), (1.3411810398101807*size, 0.9659258127212524*size, 0.0*size), (1.100000023841858*size, 0.8660253882408142*size, 0.0*size), (-1.600000262260437*size, -0.9999997615814209*size, 0.0*size), (1.0999997854232788*size, -0.8660252690315247*size, 0.0*size), (1.341180682182312*size, -0.9659257531166077*size, 0.0*size), (1.5999996662139893*size, -1.0*size, 0.0*size), (1.8588186502456665*size, -0.965925931930542*size, 0.0*size), (2.0999996662139893*size, -0.8660256266593933*size, 0.0*size), (2.3071064949035645*size, -0.7071071863174438*size, 0.0*size), (2.4660253524780273*size, -0.5000002980232239*size, 0.0*size), (2.5659255981445312*size, -0.25881943106651306*size, 0.0*size), (2.5999999046325684*size, -4.649122899991198e-07*size, 0.0*size), (2.5659260749816895*size, 0.25881853699684143*size, 0.0*size), (2.4660258293151855*size, 0.4999994933605194*size, 0.0*size), (2.3071072101593018*size, 0.707106351852417*size, 0.0*size), (2.1000006198883057*size, 0.8660250902175903*size, 0.0*size), (1.8588197231292725*size, 0.9659256339073181*size, 0.0*size), (-1.8070557117462158*size, -0.7727401852607727*size, 0.0*size), (-2.0000009536743164*size, -0.6928198337554932*size, 0.0*size), (-2.1656856536865234*size, -0.5656847357749939*size, 0.0*size), (-2.292820692062378*size, -0.3999992609024048*size, 0.0*size), (-2.3727407455444336*size, -0.20705445110797882*size, 0.0*size), (-2.3999998569488525*size, 7.336847716032935e-07*size, 0.0*size), (-2.3727405071258545*size, 0.207055926322937*size, 0.0*size), (-2.2928202152252197*size, 0.40000057220458984*size, 0.0*size), (-2.1656851768493652*size, 0.5656861066818237*size, 0.0*size), (-1.9999992847442627*size, 0.6928208470344543*size, 0.0*size), (-1.8070547580718994*size, 0.7727410197257996*size, 0.0*size), (-1.5999996662139893*size, 0.8000002503395081*size, 0.0*size), (-1.3929443359375*size, 0.7727407813072205*size, 0.0*size), (-1.1999995708465576*size, 0.6928203701972961*size, 0.0*size), (-1.0343143939971924*size, 0.5656854510307312*size, 0.0*size), (-1.0343146324157715*size, -0.5656852722167969*size, 0.0*size), (-1.2000001668930054*size, -0.6928201913833618*size, 0.0*size), (-1.3929448127746582*size, -0.7727404236793518*size, 0.0*size), (-1.6000001430511475*size, -0.7999997735023499*size, 0.0*size), (1.8070557117462158*size, 0.772739827632904*size, 0.0*size), (2.0000009536743164*size, 0.6928195953369141*size, 0.0*size), (2.1656856536865234*size, 0.5656843781471252*size, 0.0*size), (2.292820692062378*size, 0.39999890327453613*size, 0.0*size), (2.3727407455444336*size, 0.20705409348011017*size, 0.0*size), (2.3999998569488525*size, -1.0960745839838637e-06*size, 0.0*size), (2.3727405071258545*size, -0.20705628395080566*size, 0.0*size), (2.2928202152252197*size, -0.4000009298324585*size, 0.0*size), (2.1656851768493652*size, -0.5656863451004028*size, 0.0*size), (1.9999992847442627*size, -0.692821204662323*size, 0.0*size), (1.8070547580718994*size, -0.7727413773536682*size, 0.0*size), (1.5999996662139893*size, -0.8000004887580872*size, 0.0*size), (1.3929443359375*size, -0.7727410197257996*size, 0.0*size), (1.1999995708465576*size, -0.6928204894065857*size, 0.0*size), (1.0343143939971924*size, -0.5656855702400208*size, 0.0*size), (1.0343146324157715*size, 0.5656850337982178*size, 0.0*size), (1.2000004053115845*size, 0.6928199529647827*size, 0.0*size), (1.3929448127746582*size, 0.7727401852607727*size, 0.0*size), (1.6000001430511475*size, 0.7999995350837708*size, 0.0*size), ]
+ edges = [(24, 0), (1, 22), (16, 1), (17, 0), (23, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (21, 20), (22, 21), (13, 14), (14, 15), (15, 16), (17, 18), (18, 19), (19, 23), (25, 24), (26, 25), (27, 26), (28, 27), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (20, 37), (56, 38), (38, 39), (39, 40), (40, 41), (41, 42), (42, 43), (43, 44), (44, 45), (45, 46), (46, 47), (47, 48), (48, 49), (49, 50), (50, 51), (51, 52), (53, 54), (54, 55), (55, 56), (75, 57), (57, 58), (58, 59), (59, 60), (60, 61), (61, 62), (62, 63), (63, 64), (64, 65), (65, 66), (66, 67), (67, 68), (68, 69), (69, 70), (70, 71), (72, 73), (73, 74), (74, 75), (52, 72), (53, 71), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_ear_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(-2.4903741291382175e-09*size, 1.0*size, -3.123863123732917e-08*size), (-7.450580596923828e-09*size, 0.9829629063606262*size, 0.0776456817984581*size), (-1.4901161193847656e-08*size, 0.9330127239227295*size, 0.1499999761581421*size), (-2.9802322387695312e-08*size, 0.8535534143447876*size, 0.2121320217847824*size), (-2.9802322387695312e-08*size, 0.75*size, 0.25980761647224426*size), (-2.9802322387695312e-08*size, 0.6294095516204834*size, 0.2897777259349823*size), (-2.9802322387695312e-08*size, 0.5000000596046448*size, 0.29999998211860657*size), (-5.960464477539063e-08*size, 0.37059056758880615*size, 0.2897777855396271*size), (-5.960464477539063e-08*size, 0.25000008940696716*size, 0.25980767607688904*size), (-4.470348358154297e-08*size, 0.14644670486450195*size, 0.21213211119174957*size), (-4.470348358154297e-08*size, 0.06698736548423767*size, 0.15000009536743164*size), (-4.470348358154297e-08*size, 0.017037123441696167*size, 0.07764581590890884*size), (-3.6718930118695425e-08*size, 0.0*size, 1.1981423142515268e-07*size), (-2.9802322387695312e-08*size, 0.017037034034729004*size, -0.07764559239149094*size), (-2.9802322387695312e-08*size, 0.06698718667030334*size, -0.14999987185001373*size), (-1.4901161193847656e-08*size, 0.14644640684127808*size, -0.21213191747665405*size), (0.0*size, 0.24999985098838806*size, -0.25980761647224426*size), (0.0*size, 0.3705902695655823*size, -0.2897777259349823*size), (0.0*size, 0.4999997615814209*size, -0.30000004172325134*size), (0.0*size, 0.6294092535972595*size, -0.2897777855396271*size), (0.0*size, 0.7499997615814209*size, -0.2598077356815338*size), (1.4901161193847656e-08*size, 0.8535531759262085*size, -0.21213220059871674*size), (0.0*size, 0.9330125451087952*size, -0.15000019967556*size), (0.0*size, 0.9829628467559814*size, -0.07764596492052078*size), ]
+ edges = [(1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (19, 18), (20, 19), (21, 20), (22, 21), (23, 22), (0, 23), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_jaw_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), (0.0*size, 1.153113603591919*size, 0.0*size), (-0.606898307800293*size, 0.6533132195472717*size, 0.09324522316455841*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.04735109210014343*size), (-0.478340744972229*size, 0.856249213218689*size, 0.0167550016194582*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.003642391413450241*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.0003642391529865563*size), (0.0*size, 1.153113603591919*size, 0.18649044632911682*size), (-0.5728408694267273*size, 0.7130533456802368*size, 0.1391393542289734*size), (-0.478340744972229*size, 0.856249213218689*size, 0.16973544657230377*size), (-0.3405401408672333*size, 1.0092359781265259*size, 0.18284805119037628*size), (-0.1764744222164154*size, 1.1159402132034302*size, 0.1861262023448944*size), ]
+ edges = [(1, 0), (2, 1), (3, 2), (4, 3), (9, 4), (6, 5), (7, 6), (8, 7), (15, 8), (5, 0), (11, 10), (12, 11), (13, 12), (14, 13), (9, 14), (17, 16), (18, 17), (19, 18), (15, 19), (16, 10), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_teeth_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(0.6314387321472168*size, 0.4999997019767761*size, 0.09999999403953552*size), (0.5394065976142883*size, 0.29289281368255615*size, 0.09999999403953552*size), (0.3887903690338135*size, 0.1339743733406067*size, 0.09999999403953552*size), (0.19801488518714905*size, 0.03407406806945801*size, 0.09999999403953552*size), (-3.4034394502668874e-07*size, 0.0*size, 0.09999999403953552*size), (-0.19801555573940277*size, 0.034074246883392334*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, -0.10000000894069672*size), (-0.6778771877288818*size, 0.7411810755729675*size, -0.10000000894069672*size), (-0.6314389705657959*size, 0.5000001192092896*size, -0.10000000894069672*size), (-0.5394070148468018*size, 0.2928934097290039*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, -0.10000000894069672*size), (-0.19801555573940277*size, 0.034074246883392334*size, -0.10000000894069672*size), (-3.4034394502668874e-07*size, 0.0*size, -0.10000000894069672*size), (0.19801488518714905*size, 0.03407406806945801*size, -0.10000000894069672*size), (0.3887903690338135*size, 0.1339743733406067*size, -0.10000000894069672*size), (0.5394065976142883*size, 0.29289281368255615*size, -0.10000000894069672*size), (0.6314387321472168*size, 0.4999997019767761*size, -0.10000000894069672*size), (0.6778769493103027*size, 0.7411805391311646*size, -0.10000000894069672*size), (0.6999999284744263*size, 0.9999995231628418*size, -0.10000000894069672*size), (-0.38879096508026123*size, 0.13397473096847534*size, 0.09999999403953552*size), (-0.5394070148468018*size, 0.2928934097290039*size, 0.09999999403953552*size), (-0.6314389705657959*size, 0.5000001192092896*size, 0.09999999403953552*size), (-0.6778771877288818*size, 0.7411810755729675*size, 0.09999999403953552*size), (-0.7000000476837158*size, 1.0000001192092896*size, 0.09999999403953552*size), (0.6778769493103027*size, 0.7411805391311646*size, 0.09999999403953552*size), (0.6999999284744263*size, 0.9999995231628418*size, 0.09999999403953552*size), ]
+ edges = [(25, 24), (24, 0), (0, 1), (1, 2), (2, 3), (3, 4), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12), (14, 13), (15, 14), (16, 15), (17, 16), (18, 17), (4, 5), (5, 19), (19, 20), (20, 21), (21, 22), (22, 23), (18, 25), (6, 23), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+def create_face_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(-0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, 0.25*size, 0.07499998807907104*size), (0.25*size, -0.25*size, 0.07499998807907104*size), (-0.25*size, -0.25*size, -0.07499998807907104*size), (-0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, 0.25*size, -0.07499998807907104*size), (0.25*size, -0.25*size, -0.07499998807907104*size), ]
+ edges = [(4, 5), (5, 1), (1, 0), (0, 4), (5, 6), (6, 2), (2, 1), (6, 7), (7, 3), (3, 2), (7, 4), (0, 3), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_ikarrow_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, -0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, -0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.0*size, 1.0*size, -0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, -0.30000001192092896*size), (0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.0*size, 0.30000001192092896*size), (-0.10000000149011612*size, 0.699999988079071*size, 0.30000001192092896*size), (0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), (0.0*size, 1.0*size, 0.30000001192092896*size), (-0.20000000298023224*size, 0.699999988079071*size, 0.30000001192092896*size), ]
+ edges = [(0, 1), (2, 3), (1, 4), (4, 5), (3, 6), (5, 6), (0, 2), (7, 8), (9, 10), (8, 11), (11, 12), (10, 13), (12, 13), (7, 9), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
+def create_hand_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ # Create hand widget
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(0.0*size, 1.5*size, -0.7000000476837158*size), (1.1920928955078125e-07*size, -0.25*size, -0.6999999284744263*size), (0.0*size, -0.25*size, 0.7000000476837158*size), (-1.1920928955078125e-07*size, 1.5*size, 0.6999999284744263*size), (5.960464477539063e-08*size, 0.7229999899864197*size, -0.699999988079071*size), (-5.960464477539063e-08*size, 0.7229999899864197*size, 0.699999988079071*size), (1.1920928955078125e-07*size, -2.9802322387695312e-08*size, -0.699999988079071*size), (0.0*size, 2.9802322387695312e-08*size, 0.699999988079071*size), ]
+ edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7)]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+
+ mod = obj.modifiers.new("subsurf", 'SUBSURF')
+ mod.levels = 2
+ return obj
+ else:
+ return None
+
+def create_foot_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ # Create hand widget
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(-0.6999998688697815*size, -0.5242648720741272*size, 0.0*size), (-0.7000001072883606*size, 1.2257349491119385*size, 0.0*size), (0.6999998688697815*size, 1.2257351875305176*size, 0.0*size), (0.7000001072883606*size, -0.5242648720741272*size, 0.0*size), (-0.6999998688697815*size, 0.2527350187301636*size, 0.0*size), (0.7000001072883606*size, 0.2527352571487427*size, 0.0*size), (-0.7000001072883606*size, 0.975735068321228*size, 0.0*size), (0.6999998688697815*size, 0.9757352471351624*size, 0.0*size), ]
+ edges = [(1, 2), (0, 3), (0, 4), (3, 5), (4, 6), (1, 6), (5, 7), (2, 7), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+
+ mod = obj.modifiers.new("subsurf", 'SUBSURF')
+ mod.levels = 2
+ return obj
+ else:
+ return None
+
+def create_ballsocket_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != None:
+ verts = [(-0.050000108778476715*size, 0.779460072517395*size, -0.2224801927804947*size), (0.049999915063381195*size, 0.779460072517395*size, -0.22248023748397827*size), (0.09999985247850418*size, 0.6790841817855835*size, -0.3658318817615509*size), (-2.3089636158601934e-07*size, 0.5930476188659668*size, -0.488704651594162*size), (-0.10000013560056686*size, 0.6790841817855835*size, -0.3658317029476166*size), (0.04999981075525284*size, 0.6790841817855835*size, -0.36583182215690613*size), (-0.050000183284282684*size, 0.6790841817855835*size, -0.3658318519592285*size), (-0.3658319115638733*size, 0.6790841221809387*size, 0.05000019446015358*size), (-0.3658318817615509*size, 0.6790841221809387*size, -0.04999979957938194*size), (-0.36583176255226135*size, 0.6790841221809387*size, 0.10000018030405045*size), (-0.48870471119880676*size, 0.5930476188659668*size, 2.4472291215715813e-07*size), (-0.3658319413661957*size, 0.679084062576294*size, -0.0999998077750206*size), (-0.22248037159442902*size, 0.7794600129127502*size, -0.04999985918402672*size), (-0.22248034179210663*size, 0.7794600129127502*size, 0.05000016465783119*size), (0.3658319115638733*size, 0.6790841221809387*size, -0.05000000819563866*size), (0.3658319115638733*size, 0.6790841221809387*size, 0.05000000074505806*size), (0.36583179235458374*size, 0.6790841221809387*size, -0.09999998658895493*size), (0.4887046813964844*size, 0.5930476188659668*size, -3.8399143420519977e-08*size), (0.3658319413661957*size, 0.679084062576294*size, 0.10000000149011612*size), (0.050000034272670746*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.04999997466802597*size, 0.7794599533081055*size, 0.2224804311990738*size), (-0.09999992698431015*size, 0.679084062576294*size, 0.36583200097084045*size), (1.267315070663244e-07*size, 0.5930474996566772*size, 0.48870477080345154*size), (0.1000000610947609*size, 0.679084062576294*size, 0.3658318519592285*size), (-0.049999915063381195*size, 0.679084062576294*size, 0.3658319413661957*size), (0.05000007897615433*size, 0.679084062576294*size, 0.36583197116851807*size), (0.22248029708862305*size, 0.7794600129127502*size, 0.05000004544854164*size), (0.22248028218746185*size, 0.7794600129127502*size, -0.04999994859099388*size), (-4.752442350763886e-08*size, 0.8284152746200562*size, -0.1499999612569809*size), (-0.03882290795445442*size, 0.8284152746200562*size, -0.14488883316516876*size), (-0.07500004768371582*size, 0.8284152746200562*size, -0.12990377843379974*size), (-0.10606606304645538*size, 0.8284152746200562*size, -0.10606598109006882*size), (-0.1299038827419281*size, 0.8284152746200562*size, -0.07499996572732925*size), (-0.14488893747329712*size, 0.8284152746200562*size, -0.038822825998067856*size), (-0.15000006556510925*size, 0.8284152746200562*size, 2.4781975582754967e-08*size), (-0.1448889672756195*size, 0.8284152746200562*size, 0.038822878152132034*size), (-0.1299038827419281*size, 0.8284152746200562*size, 0.07500001043081284*size), (-0.10606609284877777*size, 0.8284152746200562*size, 0.1060660257935524*size), (-0.0750000923871994*size, 0.8284152746200562*size, 0.12990383803844452*size), (-0.038822952657938004*size, 0.8284152746200562*size, 0.14488889276981354*size), (-1.0593657862045802e-07*size, 0.8284152746200562*size, 0.15000005066394806*size), (0.03882275149226189*size, 0.8284152746200562*size, 0.14488892257213593*size), (0.07499989867210388*size, 0.8284152746200562*size, 0.1299038976430893*size), (0.10606591403484344*size, 0.8284152746200562*size, 0.10606611520051956*size), (0.12990373373031616*size, 0.8284152746200562*size, 0.0750000849366188*size), (0.14488881826400757*size, 0.8284152746200562*size, 0.038822952657938004*size), (0.1499999463558197*size, 0.8284152746200562*size, 1.0584351883835552e-07*size), (0.14488881826400757*size, 0.8284152746200562*size, -0.03882275149226189*size), (0.12990379333496094*size, 0.8284152746200562*size, -0.07499989122152328*size), (0.10606604814529419*size, 0.8284152746200562*size, -0.10606592148542404*size), (0.07500004768371582*size, 0.8284152746200562*size, -0.12990371882915497*size), (0.03882291540503502*size, 0.8284152746200562*size, -0.14488880336284637*size), ]
+ edges = [(1, 0), (3, 2), (5, 2), (4, 3), (6, 4), (1, 5), (0, 6), (13, 7), (12, 8), (7, 9), (9, 10), (8, 11), (27, 14), (26, 15), (14, 16), (16, 17), (15, 18), (17, 18), (10, 11), (12, 13), (20, 19), (22, 21), (24, 21), (23, 22), (29, 28), (30, 29), (31, 30), (32, 31), (33, 32), (34, 33), (35, 34), (36, 35), (37, 36), (38, 37), (39, 38), (40, 39), (41, 40), (42, 41), (43, 42), (44, 43), (45, 44), (46, 45), (47, 46), (48, 47), (49, 48), (50, 49), (51, 50), (28, 51), (26, 27), (25, 23), (20, 24), (19, 25), ]
+ faces = []
+
+ mesh = obj.data
+ mesh.from_pydata(verts, edges, faces)
+ mesh.update()
+ return obj
+ else:
+ return None
+
+
diff --git a/rigify/rigs/pitchipoy/tentacle.py b/rigify/rigs/pitchipoy/tentacle.py
new file mode 100644
index 00000000..adf0e393
--- /dev/null
+++ b/rigify/rigs/pitchipoy/tentacle.py
@@ -0,0 +1,509 @@
+import bpy
+from ...utils import copy_bone
+from ...utils import strip_org, make_deformer_name, connected_children_names
+from ...utils import make_mechanism_name, put_bone, create_sphere_widget
+from ...utils import create_widget, create_circle_widget
+from ...utils import MetarigError
+from rna_prop_ui import rna_idprop_ui_prop_get
+
+script = """
+controls = [%s]
+master_name = '%s'
+
+if is_selected( controls ):
+ layout.prop( pose_bones[ master_name ], '["%s"]', slider = True )
+ layout.prop( pose_bones[ master_name ], '["%s"]', slider = True )
+"""
+
+class Rig:
+
+ def __init__(self, obj, bone_name, params):
+ self.obj = obj
+ self.org_bones = [bone_name] + connected_children_names(obj, bone_name)
+ self.params = params
+
+ if params.tweak_extra_layers:
+ self.tweak_layers = list( params.tweak_layers )
+ else:
+ self.tweak_layers = None
+
+ if len(self.org_bones) <= 1:
+ raise MetarigError(
+ "RIGIFY ERROR: invalid rig structure" % (strip_org(bone_name))
+ )
+
+
+ def make_mch( self ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ org_bones = self.org_bones
+ mch_parent = self.obj.data.bones[ org_bones[0] ].parent
+
+ mch_parent_name = mch_parent.name # Storing the mch parent's name
+
+ if not mch_parent:
+ mch_parent = self.obj.data.edit_bones[ org_bones[0] ]
+ mch_bone = copy_bone(
+ self.obj,
+ mch_parent_name,
+ make_mechanism_name( strip_org( org_bones[0] ) )
+ )
+ else:
+ mch_bone = copy_bone(
+ self.obj,
+ mch_parent_name,
+ make_mechanism_name( strip_org( org_bones[0] ) )
+ )
+
+ put_bone( self.obj, mch_bone, eb[ mch_parent_name ].tail )
+
+ eb[ mch_bone ].length /= 4 # reduce length to fourth of original
+
+ return mch_bone
+
+
+ def make_master( self ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+
+ org_bones = self.org_bones
+
+ master_bone = copy_bone(
+ self.obj,
+ org_bones[0],
+ "master_" + strip_org( org_bones[0] )
+ )
+
+ # Make widgets
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ create_square_widget( self.obj, master_bone )
+
+ return master_bone
+
+
+ def make_controls( self ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+
+ org_bones = self.org_bones
+
+ ctrl_chain = []
+ for i in range( len( org_bones ) ):
+ name = org_bones[i]
+
+ ctrl_bone = copy_bone(
+ self.obj,
+ name,
+ strip_org(name)
+ )
+
+ ctrl_chain.append( ctrl_bone )
+
+ # Make widgets
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ for ctrl in ctrl_chain:
+ create_circle_widget(self.obj, ctrl, radius=0.3, head_tail=0.5)
+
+ return ctrl_chain
+
+
+ def make_tweaks( self ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+ org_bones = self.org_bones
+
+ tweak_chain = []
+ for i in range( len( org_bones ) + 1 ):
+ if i == len( org_bones ):
+ # Make final tweak at the tip of the tentacle
+ name = org_bones[i-1]
+ else:
+ name = org_bones[i]
+
+ tweak_bone = copy_bone(
+ self.obj,
+ name,
+ "tweak_" + strip_org(name)
+ )
+
+ tweak_e = eb[ tweak_bone ]
+
+ tweak_e.length /= 2 # Set size to half
+
+ if i == len( org_bones ):
+ # Position final tweak at the tip
+ put_bone( self.obj, tweak_bone, eb[ org_bones[-1]].tail )
+
+ tweak_chain.append( tweak_bone )
+
+ # Make widgets
+ bpy.ops.object.mode_set(mode = 'OBJECT')
+
+ for tweak in tweak_chain:
+ create_sphere_widget( self.obj, tweak )
+
+ tweak_pb = self.obj.pose.bones[ tweak ]
+
+ # Set locks
+ if tweak_chain.index( tweak ) != len( tweak_chain ) - 1:
+ tweak_pb.lock_rotation = (True, False, True)
+ tweak_pb.lock_scale = (False, True, False)
+ else:
+ tweak_pb.lock_rotation_w = True
+ tweak_pb.lock_rotation = (True, True, True)
+ tweak_pb.lock_scale = (True, True, True)
+
+ # Set up tweak bone layers
+ if self.tweak_layers:
+ tweak_pb.bone.layers = self.tweak_layers
+
+ return tweak_chain
+
+
+ def make_deform( self ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+
+ org_bones = self.org_bones
+
+ def_chain = []
+ for i in range( len( org_bones ) ):
+ name = org_bones[i]
+
+ def_bone = copy_bone(
+ self.obj,
+ name,
+ make_deformer_name(strip_org(name))
+ )
+
+ def_chain.append( def_bone )
+
+ return def_chain
+
+
+ def parent_bones( self, all_bones ):
+ bpy.ops.object.mode_set(mode ='EDIT')
+
+ org_bones = self.org_bones
+ eb = self.obj.data.edit_bones
+
+ """ for category in all_bones:
+ if isinstance( all_bones[category], list ):
+ for bone in all_bones[category]:
+ print( "Bone: " + bone )
+ eb[bone].parent = None
+ else:
+ eb[ all_bones[category] ].parent = None
+ """
+
+ # mch bone remains parentless and will be parented to root by rigify
+
+ # Parent master bone
+ # eb[ all_bones['master'] ].parent = eb[ all_bones['mch'] ]
+
+ # Parent control bones
+ # ctrls_n_parent = [ all_bones['master'] ] + all_bones['control']
+
+ for bone in ctrls_n_parent[1:]:
+ previous_index = ctrls_n_parent.index( bone ) - 1
+ eb[ bone ].parent = eb[ ctrls_n_parent[previous_index] ]
+
+ # Parent tweak bones
+ tweaks = all_bones['tweak']
+ for tweak in all_bones['tweak']:
+ parent = ''
+ if tweaks.index( tweak ) == len( tweaks ) - 1:
+ parent = all_bones['control'][ -1 ]
+ else:
+ parent = all_bones['control'][ tweaks.index( tweak ) ]
+
+ eb[ tweak ].parent = eb[ parent ]
+
+ # Parent deform bones
+ for bone in all_bones['deform'][1:]:
+ previous_index = all_bones['deform'].index( bone ) - 1
+
+ eb[ bone ].parent = eb[ all_bones['deform'][previous_index] ]
+ eb[ bone ].use_connect = True
+
+ # Parent org bones ( to tweaks by default, or to the controls )
+ for org, tweak in zip( org_bones, all_bones['tweak'] ):
+ eb[ org ].parent = eb[ tweak ]
+
+
+ def make_constraints( self, all_bones ):
+ bpy.ops.object.mode_set(mode ='OBJECT')
+
+ org_bones = self.org_bones
+ pb = self.obj.pose.bones
+
+ ## MCH bone constraints
+ if pb[ org_bones[0] ].parent:
+ mch_pb = pb[ all_bones['mch'] ]
+
+ con = mch_pb.constraints.new('COPY_LOCATION')
+ con.target = self.obj
+ con.subtarget = pb[ org_bones[0] ].parent.name
+ con.head_tail = 1.0
+
+ con = mch_pb.constraints.new('COPY_ROTATION')
+ con.target = self.obj
+ con.subtarget = pb[ org_bones[0] ].parent.name
+
+ con = mch_pb.constraints.new('COPY_SCALE')
+ con.target = self.obj
+ con.subtarget = pb[ org_bones[0] ].parent.name
+
+ """
+ # Setting the MCH prop
+ master_pb = pb[ all_bones['master'] ]
+ prop_name_r = "rotation_follow"
+ prop_name_s = "scale_follow"
+
+ prop_names = [ prop_name_r, prop_name_s ]
+
+ for prop_name in prop_names:
+ master_pb[prop_name] = 1.0
+
+ prop = rna_idprop_ui_prop_get( master_pb, prop_name )
+ prop["min"] = 0.0
+ prop["max"] = 1.0
+ prop["soft_min"] = 0.0
+ prop["soft_max"] = 1.0
+ prop["description"] = prop_name
+
+ # driving the MCH follow rotation switch
+
+ drv = mch_pb.constraints[
+ prop_names.index(prop_name) +1
+ ].driver_add("influence").driver
+
+ drv.type='SUM'
+
+ var = drv.variables.new()
+ var.name = prop_name
+ var.type = "SINGLE_PROP"
+ var.targets[0].id = self.obj
+ var.targets[0].data_path = \
+ master_pb.path_from_id() + '['+ '"' + prop_name + '"' + ']'
+
+ """
+
+ ## Deform bones' constraints
+ ctrls = all_bones['control']
+ tweaks = all_bones['tweak' ]
+ deforms = all_bones['deform' ]
+
+ for deform, tweak, ctrl in zip( deforms, tweaks, ctrls ):
+ con = pb[deform].constraints.new('COPY_TRANSFORMS')
+ con.target = self.obj
+ con.subtarget = tweak
+
+ con = pb[deform].constraints.new('DAMPED_TRACK')
+ con.target = self.obj
+ con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
+
+ con = pb[deform].constraints.new('STRETCH_TO')
+ con.target = self.obj
+ con.subtarget = tweaks[ tweaks.index( tweak ) + 1 ]
+
+ ## Control bones' constraints
+ if self.params.make_rotations:
+ if ctrl != ctrls[0]:
+ con = pb[ctrl].constraints.new('COPY_ROTATION')
+ con.target = self.obj
+ con.subtarget = ctrls[ ctrls.index(ctrl) - 1 ]
+ con.use_offset = True
+ con.target_space = 'LOCAL'
+ con.owner_space = 'LOCAL'
+
+
+ def generate(self):
+ bpy.ops.object.mode_set(mode ='EDIT')
+ eb = self.obj.data.edit_bones
+
+ # Clear all initial parenting
+ for bone in self.org_bones:
+ # eb[ bone ].parent = None
+ eb[ bone ].use_connect = False
+
+ # Creating all bones
+ mch = self.make_mch()
+ # master = self.make_master()
+ ctrl_chain = self.make_controls()
+ tweak_chain = self.make_tweaks()
+ def_chain = self.make_deform()
+
+ all_bones = {
+ 'mch' : mch,
+ # 'master' : master,
+ 'control' : ctrl_chain,
+ 'tweak' : tweak_chain,
+ 'deform' : def_chain
+ }
+
+ self.make_constraints( all_bones )
+ self.parent_bones( all_bones )
+
+ """
+ # Create UI
+ all_controls = all_bones['control'] + all_bones['tweak'] # + [ all_bones['master'] ]
+ controls_string = ", ".join(["'" + x + "'" for x in all_controls])
+ return [script % (
+ controls_string,
+ 'rotation_follow',
+ 'scale_follow'
+ )]
+ """
+
+def add_parameters(params):
+ """ Add the parameters of this rig type to the
+ RigifyParameters PropertyGroup
+ """
+ params.make_rotations = bpy.props.BoolProperty(
+ name = "Rotations",
+ default = True,
+ description = "Make bones follow parent rotation"
+ )
+
+ # Setting up extra tweak layers
+ params.tweak_extra_layers = bpy.props.BoolProperty(
+ name = "tweak_extra_layers",
+ default = True,
+ description = ""
+ )
+
+ params.tweak_layers = bpy.props.BoolVectorProperty(
+ size = 32,
+ description = "Layers for the tweak controls to be on",
+ default = tuple( [ i == 1 for i in range(0, 32) ] )
+ )
+
+
+def parameters_ui(layout, params):
+ """ Create the ui for the rig parameters.
+ """
+
+ r = layout.row()
+ r.prop(params, "make_rotations")
+
+ r = layout.row()
+ r.prop(params, "tweak_extra_layers")
+ r.active = params.tweak_extra_layers
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range( 8 ): # Layers 0-7
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range( 16, 24 ): # Layers 16-23
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ col = r.column(align=True)
+ row = col.row(align=True)
+
+ for i in range( 8, 16 ): # Layers 8-15
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+ row = col.row(align=True)
+
+ for i in range( 24, 32 ): # Layers 24-31
+ row.prop(params, "tweak_layers", index=i, toggle=True, text="")
+
+
+def create_square_widget(rig, bone_name, size=1.0, bone_transform_name=None):
+ obj = create_widget(rig, bone_name, bone_transform_name)
+ if obj != 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