1
# ##### BEGIN GPL LICENSE BLOCK #####
3
# This program is free software; you can redistribute it and/or
4
# modify it under the terms of the GNU General Public License
5
# as published by the Free Software Foundation; either version 2
6
# of the License, or (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software Foundation,
15
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
# ##### END GPL LICENSE BLOCK #####
22
from rigify import RigifyError
23
from rigify_utils import bone_class_instance, copy_bone_simple
24
from rna_prop_ui import rna_idprop_ui_prop_get
25
from mathutils import Vector, RotationMatrix
26
from math import radians, pi
28
# not used, defined for completeness
29
METARIG_NAMES = ("pelvis", "ribcage")
32
def metarig_template():
35
# generated by rigify.write_meta_rig
36
#bpy.ops.object.mode_set(mode='EDIT')
37
#obj = bpy.context.active_object
39
#bone = arm.edit_bones.new('tail.01')
40
#bone.head[:] = 0.0000, -0.0306, 0.1039
41
#bone.tail[:] = 0.0000, -0.0306, -0.0159
43
#bone.connected = False
45
#bpy.ops.object.mode_set(mode='OBJECT')
46
#pbone = obj.pose.bones['tail.01']
47
#pbone['type'] = 'tail_spline_ik'
50
def metarig_definition(obj, orig_bone_name):
51
""" Collects and returns the relevent bones for the rig.
52
The bone given is the first in the chain of tail bones.
53
It includes bones in the chain up until it hits a bone that doesn't
54
have the same name base.
56
tail.01 -> tail.02 -> tail.03 -> ... -> tail.n
59
tail_base = arm.bones[orig_bone_name]
61
if tail_base.parent == None:
62
raise RigifyError("'tail_control' rig type on bone '%s' requires a parent." % orig_bone_name)
64
bone_definitions = [tail_base.name]
65
bone_definitions.extend([child.name for child in tail_base.children_recursive_basename])
66
return bone_definitions
69
def main(obj, bone_definitions, base_names, options):
70
bpy.ops.object.mode_set(mode='EDIT')
73
eb = obj.data.edit_bones
76
# Create bones for hinge/free
77
# hinge 1 sticks with the parent
78
# hinge 2 is the parent of the tail controls
79
hinge1 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge1" % base_names[bone_definitions[0]], parent=True).name
80
hinge2 = copy_bone_simple(arm, bone_definitions[0], "MCH-%s.hinge2" % base_names[bone_definitions[0]], parent=False).name
82
# Create tail control bones
85
for bone_def in bone_definitions:
86
bone = copy_bone_simple(arm, bone_def, base_names[bone_def], parent=True).name
87
if i == 1: # Don't change parent of first tail bone
88
eb[bone].connected = False
89
eb[bone].parent = eb[hinge2]
90
eb[bone].local_location = False
95
bpy.ops.object.mode_set(mode='OBJECT')
97
# Rotation mode and axis locks
98
for bone, org_bone in zip(bones, bone_definitions):
99
pb[bone].rotation_mode = pb[org_bone].rotation_mode
100
pb[bone].lock_location = tuple(pb[org_bone].lock_location)
101
pb[bone].lock_rotations_4d = pb[org_bone].lock_rotations_4d
102
pb[bone].lock_rotation = tuple(pb[org_bone].lock_rotation)
103
pb[bone].lock_rotation_w = pb[org_bone].lock_rotation_w
104
pb[bone].lock_scale = tuple(pb[org_bone].lock_scale)
106
# Add custom properties
107
pb[bones[0]]["hinge"] = 0.0
108
prop = rna_idprop_ui_prop_get(pb[bones[0]], "hinge", create=True)
111
prop["soft_min"] = 0.0
112
prop["soft_max"] = 1.0
114
pb[bones[0]]["free"] = 0.0
115
prop = rna_idprop_ui_prop_get(pb[bones[0]], "free", create=True)
118
prop["soft_min"] = 0.0
119
prop["soft_max"] = 1.0
122
for bone, org_bone in zip(bones, bone_definitions):
123
con = pb[org_bone].constraints.new('COPY_TRANSFORMS')
127
con_f = pb[hinge2].constraints.new('COPY_LOCATION')
129
con_f.subtarget = hinge1
131
con_h = pb[hinge2].constraints.new('COPY_TRANSFORMS')
133
con_h.subtarget = hinge1
136
bone_path = pb[bones[0]].path_from_id()
138
driver_fcurve = con_f.driver_add("influence")
139
driver = driver_fcurve.driver
140
driver.type = 'AVERAGE'
141
var = driver.variables.new()
143
var.targets[0].id_type = 'OBJECT'
144
var.targets[0].id = obj
145
var.targets[0].data_path = bone_path + '["free"]'
146
mod = driver_fcurve.modifiers[0]
148
mod.coefficients[0] = 1.0
149
mod.coefficients[1] = -1.0
151
driver_fcurve = con_h.driver_add("influence")
152
driver = driver_fcurve.driver
153
driver.type = 'AVERAGE'
154
var = driver.variables.new()
156
var.targets[0].id_type = 'OBJECT'
157
var.targets[0].id = obj
158
var.targets[0].data_path = bone_path + '["hinge"]'
159
mod = driver_fcurve.modifiers[0]
161
mod.coefficients[0] = 1.0
162
mod.coefficients[1] = -1.0