Merge with trunk, revision 28528 - 28976.
[blender-staging.git] / release / scripts / modules / rigify / neck.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
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.
7 #
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.
12 #
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 import bpy
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
26
27
28 def metarig_template():
29     # TODO:
30     ## generated by rigify.write_meta_rig
31     #bpy.ops.object.mode_set(mode='EDIT')
32     #obj = bpy.context.active_object
33     #arm = obj.data
34     #bone = arm.edit_bones.new('body')
35     #bone.head[:] = 0.0000, -0.0276, -0.1328
36     #bone.tail[:] = 0.0000, -0.0170, -0.0197
37     #bone.roll = 0.0000
38     #bone.connected = False
39     #bone = arm.edit_bones.new('head')
40     #bone.head[:] = 0.0000, -0.0170, -0.0197
41     #bone.tail[:] = 0.0000, 0.0726, 0.1354
42     #bone.roll = 0.0000
43     #bone.connected = True
44     #bone.parent = arm.edit_bones['body']
45     #bone = arm.edit_bones.new('neck.01')
46     #bone.head[:] = 0.0000, -0.0170, -0.0197
47     #bone.tail[:] = 0.0000, -0.0099, 0.0146
48     #bone.roll = 0.0000
49     #bone.connected = False
50     #bone.parent = arm.edit_bones['head']
51     #bone = arm.edit_bones.new('neck.02')
52     #bone.head[:] = 0.0000, -0.0099, 0.0146
53     #bone.tail[:] = 0.0000, -0.0242, 0.0514
54     #bone.roll = 0.0000
55     #bone.connected = True
56     #bone.parent = arm.edit_bones['neck.01']
57     #bone = arm.edit_bones.new('neck.03')
58     #bone.head[:] = 0.0000, -0.0242, 0.0514
59     #bone.tail[:] = 0.0000, -0.0417, 0.0868
60     #bone.roll = 0.0000
61     #bone.connected = True
62     #bone.parent = arm.edit_bones['neck.02']
63     #bone = arm.edit_bones.new('neck.04')
64     #bone.head[:] = 0.0000, -0.0417, 0.0868
65     #bone.tail[:] = 0.0000, -0.0509, 0.1190
66     #bone.roll = 0.0000
67     #bone.connected = True
68     #bone.parent = arm.edit_bones['neck.03']
69     #bone = arm.edit_bones.new('neck.05')
70     #bone.head[:] = 0.0000, -0.0509, 0.1190
71     #bone.tail[:] = 0.0000, -0.0537, 0.1600
72     #bone.roll = 0.0000
73     #bone.connected = True
74     #bone.parent = arm.edit_bones['neck.04']
75     #
76     #bpy.ops.object.mode_set(mode='OBJECT')
77     #pbone = obj.pose.bones['head']
78     #pbone['type'] = 'neck_flex'
79     pass
80     
81
82 def metarig_definition(obj, orig_bone_name):
83     '''
84     The bone given is neck_01, its parent is the body
85     eg.
86         body -> neck_01 -> neck_02 -> neck_03.... etc
87     '''
88     arm = obj.data
89     neck = arm.bones[orig_bone_name]
90     body = neck.parent
91
92     bone_definition = [body.name, neck.name]
93     bone_definition.extend([child.name for child in neck.children_recursive_basename])
94     return bone_definition
95
96
97 def deform(obj, definitions, base_names, options):
98     for org_bone_name in definitions[1:]:
99         bpy.ops.object.mode_set(mode='EDIT')
100
101         # Create deform bone.
102         bone = copy_bone_simple(obj.data, org_bone_name, "DEF-%s" % base_names[org_bone_name], parent=True)
103
104         # Store name before leaving edit mode
105         bone_name = bone.name
106
107         # Leave edit mode
108         bpy.ops.object.mode_set(mode='OBJECT')
109
110         # Get the pose bone
111         bone = obj.pose.bones[bone_name]
112
113         # Constrain to the original bone
114         # XXX. Todo, is this needed if the bone is connected to its parent?
115         con = bone.constraints.new('COPY_TRANSFORMS')
116         con.name = "copy_loc"
117         con.target = obj
118         con.subtarget = org_bone_name
119
120
121 def main(obj, bone_definition, base_names, options):
122     from mathutils import Vector
123
124     arm = obj.data
125     eb = obj.data.edit_bones
126     bb = obj.data.bones
127     pb = obj.pose.bones
128     
129     body = bone_definition[0]
130     
131     # Create the neck and head control bones
132     if "head_name" in options:
133         head_name = options["head_name"]
134     else:
135         head_name = "head"
136     
137     neck_name = base_names[bone_definition[1]].split(".")[0]
138     
139     neck_ctrl = copy_bone_simple(arm, bone_definition[1], neck_name).name
140     head_ctrl = copy_bone_simple(arm, bone_definition[len(bone_definition)-1], head_name).name
141     eb[head_ctrl].tail += eb[neck_ctrl].head - eb[head_ctrl].head
142     eb[head_ctrl].head = eb[neck_ctrl].head
143     
144     # Create hinge and socket bones
145     neck_hinge = copy_bone_simple(arm, bone_definition[0], "MCH-" + neck_name + "_hinge").name
146     head_hinge = copy_bone_simple(arm, neck_ctrl, "MCH-" + head_name + "_hinge").name
147     eb[neck_hinge].tail += eb[neck_ctrl].head - eb[neck_hinge].head
148     eb[neck_hinge].head = eb[neck_ctrl].head
149     eb[head_hinge].tail += eb[neck_ctrl].head - eb[head_hinge].head
150     eb[head_hinge].head = eb[neck_ctrl].head
151     
152     neck_socket = copy_bone_simple(arm, bone_definition[1], "MCH-" + neck_name + "_socket").name
153     head_socket = copy_bone_simple(arm, bone_definition[1], "MCH-" + head_name + "_socket").name
154     
155     # Parent-child relationships between the body, hinges, controls, and sockets
156     eb[neck_ctrl].parent = eb[neck_hinge]
157     eb[head_ctrl].parent = eb[head_hinge]
158     
159     eb[neck_socket].parent = eb[body]
160     eb[head_socket].parent = eb[body]
161     
162     # Create neck bones
163     neck = [] # neck bones
164     neck_neck = [] # bones constrained to neck control
165     neck_head = [] # bones constrained to head control
166     for i in range(1, len(bone_definition)):
167         # Create bones
168         neck_bone = copy_bone_simple(arm, bone_definition[i], base_names[bone_definition[i]]).name
169         neck_neck_bone = copy_bone_simple(arm, neck_ctrl, "MCH-" + base_names[bone_definition[i]] + ".neck").name
170         neck_head_bone = copy_bone_simple(arm, head_ctrl, "MCH-" + base_names[bone_definition[i]] + ".head").name
171         
172         # Move them all to the same place
173         eb[neck_neck_bone].tail += eb[neck_bone].head - eb[neck_neck_bone].head
174         eb[neck_head_bone].tail += eb[neck_bone].head - eb[neck_neck_bone].head
175         eb[neck_neck_bone].head = eb[neck_bone].head
176         eb[neck_head_bone].head = eb[neck_bone].head
177         
178         # Parent/child relationships
179         eb[neck_bone].parent = eb[neck_head_bone]
180         eb[neck_head_bone].parent = eb[neck_neck_bone]
181         
182         if i > 1:
183             eb[neck_neck_bone].parent = eb[neck[i-2]]
184         else:
185             eb[neck_neck_bone].parent = eb[body]
186         
187         # Add them to the lists
188         neck += [neck_bone]
189         neck_neck += [neck_neck_bone]
190         neck_head += [neck_head_bone]
191
192     # Create deformation rig
193     deform(obj, bone_definition, base_names, options)
194
195
196     bpy.ops.object.mode_set(mode='OBJECT')
197
198     # Axis locks
199     pb[neck_ctrl].lock_location = True, True, True
200     pb[head_ctrl].lock_location = True, True, True
201     
202     for bone in neck:
203         pb[bone].lock_location = True, True, True
204
205     # Neck hinge
206     prop = rna_idprop_ui_prop_get(pb[neck_ctrl], "hinge", create=True)
207     pb[neck_ctrl]["hinge"] = 0.0
208     prop["soft_min"] = 0.0
209     prop["soft_max"] = 1.0
210     prop["hard_min"] = 0.0
211     prop["hard_max"] = 1.0
212
213     con = pb[neck_hinge].constraints.new('COPY_LOCATION')
214     con.name = "socket"
215     con.target = obj
216     con.subtarget = neck_socket
217
218     con = pb[neck_hinge].constraints.new('COPY_ROTATION')
219     con.name = "hinge"
220     con.target = obj
221     con.subtarget = body
222
223     hinge_driver_path = pb[neck_ctrl].path_from_id() + '["hinge"]'
224
225     fcurve = con.driver_add("influence")
226     driver = fcurve.driver
227     var = driver.variables.new()
228     driver.type = 'AVERAGE'
229     var.name = "var"
230     var.targets[0].id_type = 'OBJECT'
231     var.targets[0].id = obj
232     var.targets[0].data_path = hinge_driver_path
233
234     mod = fcurve.modifiers[0]
235     mod.poly_order = 1
236     mod.coefficients[0] = 1.0
237     mod.coefficients[1] = -1.0
238     
239     # Head hinge
240     prop = rna_idprop_ui_prop_get(pb[head_ctrl], "hinge", create=True)
241     pb[head_ctrl]["hinge"] = 0.0
242     prop["soft_min"] = 0.0
243     prop["soft_max"] = 1.0
244     prop["hard_min"] = 0.0
245     prop["hard_max"] = 1.0
246
247     con = pb[head_hinge].constraints.new('COPY_LOCATION')
248     con.name = "socket"
249     con.target = obj
250     con.subtarget = head_socket
251
252     con = pb[head_hinge].constraints.new('COPY_ROTATION')
253     con.name = "hinge"
254     con.target = obj
255     con.subtarget = neck_ctrl
256
257     hinge_driver_path = pb[head_ctrl].path_from_id() + '["hinge"]'
258
259     fcurve = con.driver_add("influence")
260     driver = fcurve.driver
261     var = driver.variables.new()
262     driver.type = 'AVERAGE'
263     var.name = "var"
264     var.targets[0].id_type = 'OBJECT'
265     var.targets[0].id = obj
266     var.targets[0].data_path = hinge_driver_path
267
268     mod = fcurve.modifiers[0]
269     mod.poly_order = 1
270     mod.coefficients[0] = 1.0
271     mod.coefficients[1] = -1.0
272     
273     # Neck rotation constraints
274     for i in range(0, len(neck_neck)):
275         con = pb[neck_neck[i]].constraints.new('COPY_ROTATION')
276         con.name = "neck rotation"
277         con.target = obj
278         con.subtarget = neck_ctrl
279         con.influence = (i+1) / len(neck_neck)
280         
281     
282     # Head rotation constraints/drivers
283     prop = rna_idprop_ui_prop_get(pb[head_ctrl], "extent", create=True)
284     if "extent" in options:
285         pb[head_ctrl]["extent"] = options["extent"]
286     else:
287         pb[head_ctrl]["extent"] = 0.5
288     prop["soft_min"] = 0.0
289     prop["soft_max"] = 1.0
290     prop["hard_min"] = 0.0
291     prop["hard_max"] = 1.0
292     
293     extent_prop_path = pb[head_ctrl].path_from_id() + '["extent"]'
294     
295     for i in range(0, len(neck_head)):
296         con = pb[neck_head[i]].constraints.new('COPY_ROTATION')
297         con.name = "head rotation"
298         con.target = obj
299         con.subtarget = head_ctrl
300         
301         if i < (len(neck_head)-1):
302             inf = (i+1) / len(neck_head)
303
304             fcurve = con.driver_add("influence")
305             driver = fcurve.driver
306             var = driver.variables.new()
307             var.name = "ext"
308             var.targets[0].id_type = 'OBJECT'
309             var.targets[0].id = obj
310             var.targets[0].data_path = extent_prop_path
311             
312             driver.expression = "0 if ext == 0 else (((%s-1)/ext)+1)" % inf
313         else:
314             con.influence = 1.0
315     
316     # Constrain original bones to the neck bones
317     for i in range(0, len(neck)):
318         con = pb[bone_definition[i+1]].constraints.new('COPY_TRANSFORMS')
319         con.name = "copy_transform"
320         con.target = obj
321         con.subtarget = neck[i]
322         
323     
324     # Set the controls' custom shapes to use other bones for transforms
325     pb[neck_ctrl].custom_shape_transform = pb[bone_definition[len(bone_definition)//2]]
326     pb[head_ctrl].custom_shape_transform = pb[bone_definition[len(bone_definition)-1]]
327
328
329     # last step setup layers
330     if "ex_layer" in options:
331         layer = [n==options["ex_layer"] for n in range(0,32)]
332     else:
333         layer = list(arm.bones[bone_definition[1]].layer)
334     for bone in neck:
335         bb[bone].layer = layer
336
337     layer = list(arm.bones[bone_definition[1]].layer)
338     bb[neck_ctrl].layer = layer
339     bb[head_ctrl].layer = layer
340
341
342     # no blending the result of this
343     return None
344