~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to release/scripts/modules/rigify/tongue.py

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
# not used, defined for completeness
27
 
METARIG_NAMES = ("body", "head")
28
 
 
29
 
 
30
 
def metarig_template():
31
 
    # TODO:
32
 
    ## generated by rigify.write_meta_rig
33
 
    #bpy.ops.object.mode_set(mode='EDIT')
34
 
    #obj = bpy.context.active_object
35
 
    #arm = obj.data
36
 
    #bone = arm.edit_bones.new('body')
37
 
    #bone.head[:] = 0.0000, -0.0276, -0.1328
38
 
    #bone.tail[:] = 0.0000, -0.0170, -0.0197
39
 
    #bone.roll = 0.0000
40
 
    #bone.connected = False
41
 
    #bone = arm.edit_bones.new('head')
42
 
    #bone.head[:] = 0.0000, -0.0170, -0.0197
43
 
    #bone.tail[:] = 0.0000, 0.0726, 0.1354
44
 
    #bone.roll = 0.0000
45
 
    #bone.connected = True
46
 
    #bone.parent = arm.edit_bones['body']
47
 
    #bone = arm.edit_bones.new('neck.01')
48
 
    #bone.head[:] = 0.0000, -0.0170, -0.0197
49
 
    #bone.tail[:] = 0.0000, -0.0099, 0.0146
50
 
    #bone.roll = 0.0000
51
 
    #bone.connected = False
52
 
    #bone.parent = arm.edit_bones['head']
53
 
    #bone = arm.edit_bones.new('neck.02')
54
 
    #bone.head[:] = 0.0000, -0.0099, 0.0146
55
 
    #bone.tail[:] = 0.0000, -0.0242, 0.0514
56
 
    #bone.roll = 0.0000
57
 
    #bone.connected = True
58
 
    #bone.parent = arm.edit_bones['neck.01']
59
 
    #bone = arm.edit_bones.new('neck.03')
60
 
    #bone.head[:] = 0.0000, -0.0242, 0.0514
61
 
    #bone.tail[:] = 0.0000, -0.0417, 0.0868
62
 
    #bone.roll = 0.0000
63
 
    #bone.connected = True
64
 
    #bone.parent = arm.edit_bones['neck.02']
65
 
    #bone = arm.edit_bones.new('neck.04')
66
 
    #bone.head[:] = 0.0000, -0.0417, 0.0868
67
 
    #bone.tail[:] = 0.0000, -0.0509, 0.1190
68
 
    #bone.roll = 0.0000
69
 
    #bone.connected = True
70
 
    #bone.parent = arm.edit_bones['neck.03']
71
 
    #bone = arm.edit_bones.new('neck.05')
72
 
    #bone.head[:] = 0.0000, -0.0509, 0.1190
73
 
    #bone.tail[:] = 0.0000, -0.0537, 0.1600
74
 
    #bone.roll = 0.0000
75
 
    #bone.connected = True
76
 
    #bone.parent = arm.edit_bones['neck.04']
77
 
    #
78
 
    #bpy.ops.object.mode_set(mode='OBJECT')
79
 
    #pbone = obj.pose.bones['head']
80
 
    #pbone['type'] = 'neck_flex'
81
 
    pass
82
 
    
83
 
 
84
 
def metarig_definition(obj, orig_bone_name):
85
 
    '''
86
 
    The bone given is the tongue control, its parent is the body,
87
 
    # its only child the first of a chain with matching basenames.
88
 
    eg.
89
 
        body -> tongue_control -> tongue_01 -> tongue_02 -> tongue_03.... etc
90
 
    '''
91
 
    arm = obj.data
92
 
    tongue = arm.bones[orig_bone_name]
93
 
    body = tongue.parent
94
 
 
95
 
    children = tongue.children
96
 
    if len(children) != 1:
97
 
        raise RigifyError("expected the tongue bone '%s' to have only 1 child." % orig_bone_name)
98
 
 
99
 
    child = children[0]
100
 
    bone_definition = [body.name, tongue.name, child.name]
101
 
    bone_definition.extend([child.name for child in child.children_recursive_basename])
102
 
    return bone_definition
103
 
 
104
 
 
105
 
def deform(obj, definitions, base_names, options):
106
 
    for org_bone_name in definitions[2:]:
107
 
        bpy.ops.object.mode_set(mode='EDIT')
108
 
 
109
 
        # Create deform bone.
110
 
        bone = copy_bone_simple(obj.data, org_bone_name, "DEF-%s" % base_names[org_bone_name], parent=True)
111
 
 
112
 
        # Store name before leaving edit mode
113
 
        bone_name = bone.name
114
 
 
115
 
        # Leave edit mode
116
 
        bpy.ops.object.mode_set(mode='OBJECT')
117
 
 
118
 
        # Get the pose bone
119
 
        bone = obj.pose.bones[bone_name]
120
 
 
121
 
        # Constrain to the original bone
122
 
        # XXX. Todo, is this needed if the bone is connected to its parent?
123
 
        con = bone.constraints.new('COPY_TRANSFORMS')
124
 
        con.name = "copy_loc"
125
 
        con.target = obj
126
 
        con.subtarget = org_bone_name
127
 
 
128
 
 
129
 
# TODO: rename all of the head/neck references to tongue
130
 
def main(obj, bone_definition, base_names, options):
131
 
    from mathutils import Vector
132
 
 
133
 
    arm = obj.data
134
 
 
135
 
    # Initialize container classes for convenience
136
 
    mt = bone_class_instance(obj, ["body", "head"]) # meta
137
 
    mt.body = bone_definition[0]
138
 
    mt.head = bone_definition[1]
139
 
    mt.update()
140
 
 
141
 
    neck_chain = bone_definition[2:]
142
 
 
143
 
    mt_chain = bone_class_instance(obj, [("neck_%.2d" % (i + 1)) for i in range(len(neck_chain))]) # 99 bones enough eh?
144
 
    for i, attr in enumerate(mt_chain.attr_names):
145
 
        setattr(mt_chain, attr, neck_chain[i])
146
 
    mt_chain.update()
147
 
 
148
 
    neck_chain_basename = base_names[mt_chain.neck_01_e.name].split(".")[0]
149
 
    neck_chain_segment_length = mt_chain.neck_01_e.length
150
 
 
151
 
    ex = bone_class_instance(obj, ["head", "head_hinge", "neck_socket", "head_ctrl"]) # hinge & extras
152
 
 
153
 
    # Add the head hinge at the bodys location, becomes the parent of the original head
154
 
 
155
 
    # apply everything to this copy of the chain
156
 
    ex_chain = mt_chain.copy(base_names=base_names)
157
 
    ex_chain.neck_01_e.parent = mt_chain.neck_01_e.parent
158
 
 
159
 
 
160
 
    # Copy the head bone and offset
161
 
    ex.head_e = copy_bone_simple(arm, mt.head, "MCH-%s" % base_names[mt.head], parent=True)
162
 
    ex.head_e.connected = False
163
 
    ex.head = ex.head_e.name
164
 
    # offset
165
 
    head_length = ex.head_e.length
166
 
    ex.head_e.head.y += head_length / 2.0
167
 
    ex.head_e.tail.y += head_length / 2.0
168
 
 
169
 
    # Yes, use the body bone but call it a head hinge
170
 
    ex.head_hinge_e = copy_bone_simple(arm, mt.body, "MCH-%s_hinge" % base_names[mt.head], parent=False)
171
 
    ex.head_hinge_e.connected = False
172
 
    ex.head_hinge = ex.head_hinge_e.name
173
 
    ex.head_hinge_e.head.y += head_length / 4.0
174
 
    ex.head_hinge_e.tail.y += head_length / 4.0
175
 
 
176
 
    # Insert the neck socket, the head copys this loation
177
 
    ex.neck_socket_e = arm.edit_bones.new("MCH-%s_socked" % neck_chain_basename)
178
 
    ex.neck_socket = ex.neck_socket_e.name
179
 
    ex.neck_socket_e.connected = False
180
 
    ex.neck_socket_e.parent = mt.body_e
181
 
    ex.neck_socket_e.head = mt.head_e.head
182
 
    ex.neck_socket_e.tail = mt.head_e.head - Vector((0.0, neck_chain_segment_length / 2.0, 0.0))
183
 
    ex.neck_socket_e.roll = 0.0
184
 
 
185
 
 
186
 
    # copy of the head for controling
187
 
    ex.head_ctrl_e = copy_bone_simple(arm, mt.head, base_names[mt.head])
188
 
    ex.head_ctrl = ex.head_ctrl_e.name
189
 
    ex.head_ctrl_e.parent = ex.head_hinge_e
190
 
 
191
 
    for i, attr in enumerate(ex_chain.attr_names):
192
 
        neck_e = getattr(ex_chain, attr + "_e")
193
 
 
194
 
        # dont store parent names, re-reference as each chain bones parent.
195
 
        neck_e_parent = arm.edit_bones.new("MCH-rot_%s" % base_names[getattr(mt_chain, attr)])
196
 
        neck_e_parent.head = neck_e.head
197
 
        neck_e_parent.tail = neck_e.head + (mt.head_e.vector.normalize() * neck_chain_segment_length / 2.0)
198
 
        neck_e_parent.roll = mt.head_e.roll
199
 
 
200
 
        orig_parent = neck_e.parent
201
 
        neck_e.connected = False
202
 
        neck_e.parent = neck_e_parent
203
 
        neck_e_parent.connected = False
204
 
 
205
 
        if i == 0:
206
 
            neck_e_parent.parent = mt.body_e
207
 
        else:
208
 
            neck_e_parent.parent = orig_parent
209
 
 
210
 
    deform(obj, bone_definition, base_names, options)
211
 
 
212
 
    bpy.ops.object.mode_set(mode='OBJECT')
213
 
 
214
 
    mt.update()
215
 
    mt_chain.update()
216
 
    ex_chain.update()
217
 
    ex.update()
218
 
 
219
 
    # Axis locks
220
 
    ex.head_ctrl_p.lock_location = True, True, True
221
 
    ex.head_ctrl_p.lock_scale = True, False, True
222
 
 
223
 
    # Simple one off constraints, no drivers
224
 
    con = ex.head_ctrl_p.constraints.new('COPY_LOCATION')
225
 
    con.target = obj
226
 
    con.subtarget = ex.neck_socket
227
 
 
228
 
    con = ex.head_p.constraints.new('COPY_ROTATION')
229
 
    con.target = obj
230
 
    con.subtarget = ex.head_ctrl
231
 
 
232
 
    # driven hinge
233
 
    prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, "hinge", create=True)
234
 
    ex.head_ctrl_p["hinge"] = 0.0
235
 
    prop["soft_min"] = 0.0
236
 
    prop["soft_max"] = 1.0
237
 
 
238
 
    con = ex.head_hinge_p.constraints.new('COPY_ROTATION')
239
 
    con.name = "hinge"
240
 
    con.target = obj
241
 
    con.subtarget = mt.body
242
 
 
243
 
    # add driver
244
 
    hinge_driver_path = ex.head_ctrl_p.path_to_id() + '["hinge"]'
245
 
 
246
 
    fcurve = con.driver_add("influence")
247
 
    driver = fcurve.driver
248
 
    var = driver.variables.new()
249
 
    driver.type = 'AVERAGE'
250
 
    var.name = "var"
251
 
    var.targets[0].id_type = 'OBJECT'
252
 
    var.targets[0].id = obj
253
 
    var.targets[0].data_path = hinge_driver_path
254
 
 
255
 
    #mod = fcurve_driver.modifiers.new('GENERATOR')
256
 
    mod = fcurve.modifiers[0]
257
 
    mod.poly_order = 1
258
 
    mod.coefficients[0] = 1.0
259
 
    mod.coefficients[1] = -1.0
260
 
 
261
 
    head_driver_path = ex.head_ctrl_p.path_to_id()
262
 
 
263
 
    target_names = [("b%.2d" % (i + 1)) for i in range(len(neck_chain))]
264
 
 
265
 
    ex.head_ctrl_p["bend_tot"] = 0.0
266
 
    fcurve = ex.head_ctrl_p.driver_add('["bend_tot"]')
267
 
    driver = fcurve.driver
268
 
    driver.type = 'SUM'
269
 
    fcurve.modifiers.remove(0) # grr dont need a modifier
270
 
 
271
 
    for i in range(len(neck_chain)):
272
 
        var = driver.variables.new()
273
 
        var.name = target_names[i]
274
 
        var.targets[0].id_type = 'OBJECT'
275
 
        var.targets[0].id = obj
276
 
        var.targets[0].data_path = head_driver_path + ('["bend_%.2d"]' % (i + 1))
277
 
 
278
 
 
279
 
    for i, attr in enumerate(ex_chain.attr_names):
280
 
        neck_p = getattr(ex_chain, attr + "_p")
281
 
        neck_p.lock_location = True, True, True
282
 
        neck_p.lock_location = True, True, True
283
 
        neck_p.lock_rotations_4d = True
284
 
 
285
 
        # Add bend prop
286
 
        prop_name = "bend_%.2d" % (i + 1)
287
 
        prop = rna_idprop_ui_prop_get(ex.head_ctrl_p, prop_name, create=True)
288
 
        ex.head_ctrl_p[prop_name] = 1.0
289
 
        prop["soft_min"] = 0.0
290
 
        prop["soft_max"] = 1.0
291
 
 
292
 
        # add parent constraint
293
 
        neck_p_parent = neck_p.parent
294
 
 
295
 
        # add constraints
296
 
        if i == 0:
297
 
            con = neck_p.constraints.new('COPY_SCALE')
298
 
            con.name = "Copy Scale"
299
 
            con.target = obj
300
 
            con.subtarget = ex.head_ctrl
301
 
            con.owner_space = 'LOCAL'
302
 
            con.target_space = 'LOCAL'
303
 
        
304
 
        con = neck_p_parent.constraints.new('COPY_ROTATION')
305
 
        con.name = "Copy Rotation"
306
 
        con.target = obj
307
 
        con.subtarget = ex.head
308
 
        con.owner_space = 'LOCAL'
309
 
        con.target_space = 'LOCAL'
310
 
 
311
 
        fcurve = con.driver_add("influence")
312
 
        driver = fcurve.driver
313
 
        driver.type = 'SCRIPTED'
314
 
        driver.expression = "bend/bend_tot"
315
 
 
316
 
        fcurve.modifiers.remove(0) # grr dont need a modifier
317
 
 
318
 
 
319
 
        # add target
320
 
        var = driver.variables.new()
321
 
        var.name = "bend_tot"
322
 
        var.targets[0].id_type = 'OBJECT'
323
 
        var.targets[0].id = obj
324
 
        var.targets[0].data_path = head_driver_path + ('["bend_tot"]')
325
 
 
326
 
        var = driver.variables.new()
327
 
        var.name = "bend"
328
 
        var.targets[0].id_type = 'OBJECT'
329
 
        var.targets[0].id = obj
330
 
        var.targets[0].data_path = head_driver_path + ('["%s"]' % prop_name)
331
 
 
332
 
 
333
 
        # finally constrain the original bone to this one
334
 
        orig_neck_p = getattr(mt_chain, attr + "_p")
335
 
        con = orig_neck_p.constraints.new('COPY_TRANSFORMS')
336
 
        con.target = obj
337
 
        con.subtarget = neck_p.name
338
 
 
339
 
 
340
 
    # Set the head control's custom shape to use the last
341
 
    # org neck bone for its transform
342
 
    ex.head_ctrl_p.custom_shape_transform = obj.pose.bones[bone_definition[len(bone_definition)-1]]
343
 
 
344
 
 
345
 
    # last step setup layers
346
 
    if "ex_layer" in options:
347
 
        layer = [n==options["ex_layer"] for n in range(0,32)]
348
 
    else:
349
 
        layer = list(arm.bones[bone_definition[1]].layer)
350
 
    for attr in ex_chain.attr_names:
351
 
        getattr(ex_chain, attr + "_b").layer = layer
352
 
    for attr in ex.attr_names:
353
 
        getattr(ex, attr + "_b").layer = layer
354
 
 
355
 
    layer = list(arm.bones[bone_definition[1]].layer)
356
 
    ex.head_ctrl_b.layer = layer
357
 
 
358
 
 
359
 
    # no blending the result of this
360
 
    return None
361