~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to release/scripts/addons_contrib/io_import_lipSync_Importer.py

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-05-12 20:02:22 UTC
  • mfrom: (14.2.16 sid)
  • Revision ID: package-import@ubuntu.com-20120512200222-lznjs2cxzaq96wua
Tags: 2.63a-1
* New upstream bugfix release
  + debian/patches/: re-worked since source code changed

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
 
bl_info = {
20
 
    "name": "LipSync Importer & Blinker",
21
 
    "author": "Yousef Harfoush - bat3a ;)",
22
 
    "version": (0, 5, 0),
23
 
    "blender": (2, 6, 2),
24
 
    "location": "3D window > Tool Shelf",
25
 
    "description": "Plot Moho (Papagayo, Jlipsync, Yolo) file to frames and adds automatic blinking",
26
 
    "warning": "",
27
 
    "wiki_url": "http://wiki.blender.org/index.php?title=Extensions:2.5/Py/Scripts/Import-Export/Lipsync_Importer",
28
 
    "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=24080&group_id=153&atid=468",
29
 
    "category": "Import-Export"}
30
 
 
31
 
 
32
 
import bpy, re
33
 
from random import random
34
 
from bpy.props import *
35
 
from bpy.props import IntProperty, FloatProperty, StringProperty
36
 
 
37
 
global lastPhoneme
38
 
lastPhoneme="nothing"
39
 
 
40
 
# truning off relative path - it causes an error if it was true
41
 
if bpy.context.user_preferences.filepaths.use_relative_paths == True:
42
 
    bpy.context.user_preferences.filepaths.use_relative_paths = False
43
 
 
44
 
# add blinking
45
 
def blinker():
46
 
    
47
 
    scn = bpy.context.scene
48
 
    obj = bpy.context.object
49
 
 
50
 
    if scn.regMenuTypes.enumBlinkTypes == '0':
51
 
        modifier = 0
52
 
    elif scn.regMenuTypes.enumBlinkTypes == '1':
53
 
        modifier = scn.blinkMod
54
 
    
55
 
    #creating keys with blinkNm count
56
 
    for y in range(scn.blinkNm):
57
 
        frame = y * scn.blinkSp + int(random()*modifier)
58
 
        createShapekey('blink', frame)
59
 
 
60
 
# -----------code contributed by dalai felinto adds armature support modified by me-------------------
61
 
 
62
 
bone_keys = {
63
 
"AI":   ('location', 0),
64
 
"E":    ('location', 1),
65
 
"FV":   ('location', 2),
66
 
"L":    ('rotation_euler', 0),
67
 
"MBP":  ('rotation_euler', 1),
68
 
"O":    ('rotation_euler', 2),
69
 
"U":    ('scale', 0),
70
 
"WQ":   ('scale', 1),
71
 
"etc":  ('scale', 2),
72
 
"rest": ('ik_stretch', -1)
73
 
}
74
 
 
75
 
def lipsyncerBone():
76
 
    # reading imported file & creating keys
77
 
    object = bpy.context.object
78
 
    scene = bpy.context.scene
79
 
    bone = bpy.context.active_pose_bone
80
 
    
81
 
    resetBoneScale(bone)
82
 
    
83
 
    f=open(scene.fpath) # importing file
84
 
    f.readline() # reading the 1st line that we don"t need
85
 
    
86
 
    for line in f:
87
 
        # removing new lines
88
 
        lsta = re.split("\n+", line)
89
 
 
90
 
        # building a list of frames & shapes indexes
91
 
        lst = re.split(":? ", lsta[0])# making a list of a frame & number 
92
 
        frame = int(lst[0])
93
 
        
94
 
        for key,attribute in bone_keys.items():
95
 
            if lst[1] == key:
96
 
                createBoneKeys(key, bone, attribute, frame)
97
 
 
98
 
def resetBoneScale(bone):
99
 
    # set the attributes used by papagayo to 0.0
100
 
    for attribute,index in bone_keys.values():
101
 
        if index != -1:
102
 
            #bone.location[0] = 0.0
103
 
            exec("bone.%s[%d] = %f" % (attribute, index, 0.0))
104
 
        else:
105
 
            exec("bone.%s = %f" % (attribute, 0.0))
106
 
 
107
 
def addBoneKey(bone, data_path, index=-1, value=None, frame=bpy.context.scene.frame_current, group=""):
108
 
    # set a value and keyframe for the bone
109
 
    # it assumes the 'bone' variable was defined before
110
 
    # and it's the current selected bone
111
 
 
112
 
    if value != None:
113
 
        if index != -1:
114
 
            # bone.location[0] = 0.0
115
 
            exec("bone.%s[%d] = %f" % (data_path, index, value))
116
 
        else:
117
 
            exec("bone.%s = %f" % (data_path, value))
118
 
 
119
 
    # bone.keyframe_insert("location", 0, 10.0, "Lipsync")
120
 
    exec('bone.keyframe_insert("%s", %d, %f, "%s")' % (data_path, index, frame, group))
121
 
 
122
 
# creating keys with offset and eases for a phonem @ the Skframe
123
 
def createBoneKeys(phoneme, bone, attribute, frame):
124
 
    global lastPhoneme
125
 
    
126
 
    scene = bpy.context.scene
127
 
    object = bpy.context.object
128
 
    
129
 
    offst = scene.offset     # offset value
130
 
    skVlu = scene.skscale    # shape key value
131
 
    
132
 
    #in case of Papagayo format
133
 
    if scene.regMenuTypes.enumFileTypes == '0' :
134
 
        frmIn = scene.easeIn     # ease in value
135
 
        frmOut = scene.easeOut   # ease out value
136
 
        hldIn = scene.holdGap    # holding time value
137
 
        
138
 
    #in case of Jlipsync format or Yolo
139
 
    elif scene.regMenuTypes.enumFileTypes == '1' :
140
 
        frmIn = 1
141
 
        frmOut = 1
142
 
        hldIn = 0
143
 
 
144
 
    # inserting the In key only when phonem change or when blinking
145
 
    if lastPhoneme!=phoneme or eval(scene.regMenuTypes.enumModeTypes) == 1:
146
 
        addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame-frmIn, "Lipsync")
147
 
 
148
 
    addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame, "Lipsync")
149
 
    addBoneKey(bone, attribute[0], attribute[1], skVlu, offst+frame+hldIn, "Lipsync")
150
 
    addBoneKey(bone, attribute[0], attribute[1], 0.0, offst+frame+hldIn+frmOut, "Lipsync")
151
 
    
152
 
    lastPhoneme=phoneme
153
 
 
154
 
# -------------------------------------------------------------------------------
155
 
 
156
 
# reading imported file & creating keys
157
 
def lipsyncer():
158
 
    
159
 
    obj = bpy.context.object
160
 
    scn = bpy.context.scene
161
 
    
162
 
    f=open(scn.fpath) # importing file
163
 
    f.readline() # reading the 1st line that we don"t need
164
 
    
165
 
    for line in f:
166
 
 
167
 
        # removing new lines
168
 
        lsta = re.split("\n+", line)
169
 
 
170
 
        # building a list of frames & shapes indexes
171
 
        lst = re.split(":? ", lsta[0])# making a list of a frame & number 
172
 
        frame = int(lst[0])
173
 
        
174
 
        for key in obj.data.shape_keys.key_blocks:
175
 
            if lst[1] == key.name:
176
 
                createShapekey(key.name, frame)
177
 
 
178
 
# creating keys with offset and eases for a phonem @ the frame
179
 
def createShapekey(phoneme, frame):
180
 
    
181
 
    global lastPhoneme
182
 
    
183
 
    scn = bpy.context.scene
184
 
    obj = bpy.context.object
185
 
    objSK = obj.data.shape_keys
186
 
    
187
 
    offst = scn.offset     # offset value
188
 
    skVlu = scn.skscale    # shape key value
189
 
    
190
 
    #in case of Papagayo format
191
 
    if scn.regMenuTypes.enumFileTypes == '0' :
192
 
        frmIn = scn.easeIn     # ease in value
193
 
        frmOut = scn.easeOut   # ease out value
194
 
        hldIn = scn.holdGap    # holding time value
195
 
        
196
 
    #in case of Jlipsync format or Yolo
197
 
    elif scn.regMenuTypes.enumFileTypes == '1' :
198
 
        frmIn = 1
199
 
        frmOut = 1
200
 
        hldIn = 0
201
 
 
202
 
    # inserting the In key only when phonem change or when blinking
203
 
    if lastPhoneme!=phoneme or eval(scn.regMenuTypes.enumModeTypes) == 1:
204
 
        objSK.key_blocks[phoneme].value=0.0
205
 
        objSK.key_blocks[phoneme].keyframe_insert("value",
206
 
            -1, offst+frame-frmIn, "Lipsync")
207
 
            
208
 
    objSK.key_blocks[phoneme].value=skVlu
209
 
    objSK.key_blocks[phoneme].keyframe_insert("value", 
210
 
        -1, offst+frame, "Lipsync")
211
 
    
212
 
    objSK.key_blocks[phoneme].value=skVlu
213
 
    objSK.key_blocks[phoneme].keyframe_insert("value", 
214
 
        -1, offst+frame+hldIn, "Lipsync")
215
 
            
216
 
    objSK.key_blocks[phoneme].value=0.0
217
 
    objSK.key_blocks[phoneme].keyframe_insert("value", 
218
 
    -1, offst+frame+hldIn+frmOut, "Lipsync")
219
 
    
220
 
    lastPhoneme = phoneme
221
 
 
222
 
# lipsyncer operation start
223
 
class btn_lipsyncer(bpy.types.Operator):
224
 
    bl_idname = 'lipsync.go'
225
 
    bl_label = 'Start Processing'
226
 
    bl_description = 'Plots the voice file keys to timeline'
227
 
 
228
 
    def execute(self, context):
229
 
 
230
 
        scn = context.scene
231
 
        obj = context.active_object
232
 
 
233
 
        # testing if object is valid
234
 
        if obj!=None:
235
 
            if obj.type=="MESH":
236
 
                if obj.data.shape_keys!=None:
237
 
                    if scn.fpath!='': lipsyncer()
238
 
                    else: print ("select a Moho file")
239
 
                else: print("No shape keys")
240
 
    
241
 
            elif obj.type=="ARMATURE":
242
 
                if 1:#XXX add prop test
243
 
                    if scn.fpath!='': lipsyncerBone()
244
 
                    else: print ("select a Moho file")
245
 
                else: print("Create Pose properties")
246
 
                
247
 
            else: print ("Object is not a mesh ot bone")
248
 
        else: print ("Select object")
249
 
        return {'FINISHED'}
250
 
 
251
 
# blinker operation start
252
 
class btn_blinker(bpy.types.Operator):
253
 
    bl_idname = 'blink.go'
254
 
    bl_label = 'Start Processing'
255
 
    bl_description = 'Add blinks at random or specifice frames'
256
 
 
257
 
    def execute(self, context):
258
 
        
259
 
        scn = context.scene
260
 
        obj = context.object
261
 
 
262
 
         # testing if object is valid
263
 
        if obj!=None:
264
 
            if obj.type=="MESH":
265
 
                if obj.data.shape_keys!=None:
266
 
                    for key in obj.data.shape_keys.key_blocks:
267
 
                        if key.name=='blink':
268
 
                            blinker()
269
 
                            #return
270
 
                else: print("No shape keys")
271
 
            else: print ("Object is not a mesh ot bone")
272
 
        else: print ("Select object")
273
 
        return {'FINISHED'}
274
 
 
275
 
 
276
 
#defining custom enumeratos
277
 
class menuTypes(bpy.types.PropertyGroup):
278
 
 
279
 
    enumFileTypes = EnumProperty(items =(('0', 'Papagayo', ''), 
280
 
                                         ('1', 'Jlipsync Or Yolo', '')
281
 
                                       #,('2', 'Retarget', '')
282
 
                                         ),
283
 
                                 name = 'Choose FileType',
284
 
                                 default = '0')
285
 
 
286
 
    enumBlinkTypes = EnumProperty(items =(('0', 'Specific', ''),
287
 
                                          ('1', 'Random','')),
288
 
                                  name = 'Choose BlinkType',
289
 
                                  default = '0')
290
 
 
291
 
    enumModeTypes = EnumProperty(items =(('0', 'Lipsyncer',''),
292
 
                                         ('1', 'Blinker','')),
293
 
                                 name = 'Choose Mode',
294
 
                                 default = '0')
295
 
                                 
296
 
# drawing the user interface
297
 
class LipSyncBoneUI(bpy.types.Panel):
298
 
    bl_space_type = "VIEW_3D"
299
 
    bl_region_type = "UI"
300
 
    bl_label = "Phonemes"
301
 
    
302
 
    def draw(self, context):
303
 
        layout = self.layout
304
 
        col = layout.column()
305
 
 
306
 
        bone = bpy.context.active_pose_bone
307
 
        
308
 
        #showing the current object type
309
 
        if bone: #and if scn.regMenuTypes.enumModeTypes == '0':
310
 
            col.prop(bone, "location", index=0, text="AI")
311
 
            col.prop(bone, "location", index=1, text="E")
312
 
            col.prop(bone, "location", index=2, text="FV")
313
 
            if bpy.context.scene.unit_settings.system_rotation == 'RADIANS':
314
 
                col.prop(bone, "rotation_euler", index=0, text="L")
315
 
                col.prop(bone, "rotation_euler", index=1, text="MBP")
316
 
                col.prop(bone, "rotation_euler", index=2, text="O")
317
 
            else:
318
 
                row=col.row()
319
 
                row.prop(bone, "rotation_euler", index=0, text="L")
320
 
                row.label(text=str("%4.2f" % (bone.rotation_euler.x)))
321
 
                row=col.row()
322
 
                row.prop(bone, "rotation_euler", index=1, text="MBP")
323
 
                row.label(text=str("%4.2f" % (bone.rotation_euler.y)))
324
 
                row=col.row()
325
 
                row.prop(bone, "rotation_euler", index=2, text="O")
326
 
                row.label(text=str("%4.2f" % (bone.rotation_euler.z)))
327
 
            col.prop(bone, "scale", index=0, text="U")
328
 
            col.prop(bone, "scale", index=1, text="WQ")
329
 
            col.prop(bone, "scale", index=2, text="etc")
330
 
        else:
331
 
            layout.label(text="No good bone is selected")
332
 
            
333
 
# drawing the user interface
334
 
class LipSyncUI(bpy.types.Panel):
335
 
    bl_space_type = "VIEW_3D"
336
 
    bl_region_type = "TOOL_PROPS"
337
 
    bl_label = "LipSync Importer & Blinker"
338
 
    
339
 
    newType= bpy.types.Scene
340
 
    scn = bpy.context.scene
341
 
    
342
 
    newType.fpath = StringProperty(name="Import File ", description="Select your voice file", subtype="FILE_PATH")
343
 
    newType.skscale = FloatProperty(description="Smoothing shape key values", min=0.1, max=1.0, default=0.8)
344
 
    newType.offset = IntProperty(description="Offset your frames", default=0)
345
 
 
346
 
    newType.easeIn = IntProperty(description="Smoothing In curve", min=1, default=3)
347
 
    newType.easeOut = IntProperty(description="Smoothing Out curve", min=1, default=3)
348
 
    newType.holdGap = IntProperty(description="Holding for slow keys", min=0, default=0)
349
 
 
350
 
    newType.blinkSp = IntProperty(description="Space between blinks", min=1, default=100)
351
 
    newType.blinkNm = IntProperty(description="Number of blinks", min=1, default=10)
352
 
    
353
 
    newType.blinkMod = IntProperty(description="Randomzing keyframe placment", min=1, default=10)
354
 
    
355
 
    def draw(self, context):
356
 
        
357
 
        obj = bpy.context.active_object
358
 
        scn = bpy.context.scene
359
 
        
360
 
        layout = self.layout
361
 
        col = layout.column()
362
 
 
363
 
        # showing the current object type
364
 
        if obj != None:
365
 
            if obj.type == "MESH":
366
 
                split = col.split(align=True)
367
 
                split.label(text="The active object is: ", icon="OBJECT_DATA")
368
 
                split.label(obj.name, icon="EDITMODE_HLT")
369
 
            elif obj.type == "ARMATURE": # bone needs to be selected
370
 
                if obj.mode == "POSE": # mode needs to be pose
371
 
                    split = col.split(align=True)
372
 
                    split.label(text="The active object is: ", icon="ARMATURE_DATA")
373
 
                    split.label(obj.name, icon="EDITMODE_HLT")
374
 
                else:
375
 
                    col.label(text="You need to select Pose mode!", icon="OBJECT_DATA")
376
 
            else:
377
 
                col.label(text="The active object is not a Mesh or Armature!", icon="OBJECT_DATA")
378
 
        else:
379
 
            layout.label(text="No object is selected", icon="OBJECT_DATA")
380
 
            
381
 
        col.row().prop(scn.regMenuTypes, 'enumModeTypes')
382
 
        col.separator()
383
 
        
384
 
        # the lipsyncer panel 
385
 
        if scn.regMenuTypes.enumModeTypes == '0':
386
 
            # choose the file format
387
 
            col.row().prop(scn.regMenuTypes, 'enumFileTypes', text = ' ', expand = True)
388
 
                
389
 
            # Papagayo panel
390
 
            if scn.regMenuTypes.enumFileTypes == '0':
391
 
                col.prop(context.scene, "fpath")
392
 
                split = col.split(align=True)
393
 
                split.label("Key Value :")
394
 
                split.prop(context.scene, "skscale")
395
 
                split = col.split(align=True)
396
 
                split.label("Frame Offset :")
397
 
                split.prop(context.scene, "offset")
398
 
                split = col.split(align=True)
399
 
                split.prop(context.scene, "easeIn", "Ease In")
400
 
                split.prop(context.scene, "holdGap", "Hold Gap")
401
 
                split.prop(context.scene, "easeOut", "Ease Out")
402
 
                
403
 
                col.operator('lipsync.go', text='Plot Keys to the Timeline')
404
 
 
405
 
            # Jlipsync & Yolo panel
406
 
            elif scn.regMenuTypes.enumFileTypes == '1':
407
 
                col.prop(context.scene, "fpath")
408
 
                split = col.split(align=True)
409
 
                split.label("Key Value :")
410
 
                split.prop(context.scene, "skscale")
411
 
                split = col.split(align=True)
412
 
                split.label("Frame Offset :")
413
 
                split.prop(context.scene, "offset")
414
 
                
415
 
                col.operator('lipsync.go', text='Plot Keys to the Timeline')
416
 
        
417
 
        # the blinker panel
418
 
        elif scn.regMenuTypes.enumModeTypes == '1':
419
 
            # choose blink type
420
 
            col.row().prop(scn.regMenuTypes, 'enumBlinkTypes', text = ' ', expand = True)
421
 
            
422
 
            # specific panel
423
 
            if scn.regMenuTypes.enumBlinkTypes == '0':
424
 
                split = col.split(align=True)
425
 
                split.label("Key Value :")
426
 
                split.prop(context.scene, "skscale")
427
 
                split = col.split(align=True)
428
 
                split.label("Frame Offset :")
429
 
                split.prop(context.scene, "offset")
430
 
                split = col.split(align=True)
431
 
                split.prop(context.scene, "easeIn", "Ease In")
432
 
                split.prop(context.scene, "holdGap", "Hold Gap")
433
 
                split.prop(context.scene, "easeOut", "Ease Out")
434
 
                col.prop(context.scene, "blinkSp", "Spacing")
435
 
                col.prop(context.scene, "blinkNm", "Times")
436
 
                col.operator('blink.go', text='Add Keys to the Timeline')
437
 
            
438
 
            # Random panel
439
 
            elif scn.regMenuTypes.enumBlinkTypes == '1':
440
 
                split = col.split(align=True)
441
 
                split.label("Key Value :")
442
 
                split.prop(context.scene, "skscale")
443
 
                split = col.split(align=True)
444
 
                split.label("Frame Start :")
445
 
                split.prop(context.scene, "offset")
446
 
                split = col.split(align=True)
447
 
                split.prop(context.scene, "easeIn", "Ease In")
448
 
                split.prop(context.scene, "holdGap", "Hold Gap")
449
 
                split.prop(context.scene, "easeOut", "Ease Out")
450
 
                split = col.split(align=True)
451
 
                split.prop(context.scene, "blinkSp", "Spacing")
452
 
                split.prop(context.scene, "blinkMod", "Random Modifier")
453
 
                col.prop(context.scene, "blinkNm", "Times")
454
 
                col.operator('blink.go', text='Add Keys to the Timeline')
455
 
        
456
 
        
457
 
# clearing vars
458
 
def clear_properties():
459
 
 
460
 
    # can happen on reload
461
 
    if bpy.context.scene is None:
462
 
        return
463
 
     
464
 
    props = ["fpath", "skscale", "offset", "easeIn", "easeOut", "holdGap", "blinkSp", "blinkNm", "blinkMod"]
465
 
    for p in props:
466
 
        if p in bpy.types.Scene.bl_rna.properties:
467
 
            exec("del bpy.types.Scene."+p)
468
 
        if p in bpy.context.scene:
469
 
            del bpy.context.scene[p]
470
 
 
471
 
# registering the script
472
 
def register():
473
 
    bpy.utils.register_module(__name__)
474
 
    bpy.types.Scene.regMenuTypes = PointerProperty(type = menuTypes)
475
 
 
476
 
def unregister():
477
 
    bpy.utils.unregister_module(__name__)
478
 
    del bpy.context.scene.regMenuTypes
479
 
 
480
 
    clear_properties()
481
 
 
482
 
if __name__ == "__main__":
483
 
    register()