facial.py
5.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# -*- coding: UTF-8 -*-
import bpy
import util
# duracao na posicao selecionada
dict_duration = {
'lento': 15,
'normal': 10,
'rapido': 5
}
# tempo de entrada e saida na posicao selecionada
dict_transition = {
'lento': 15,
'normal': 10,
'rapido': 5
}
# insere keyframes aos bones selecionados anteriormente e passados como parametro
def keyframe_insert(current_frame = 0, pose_bones = bpy.context.object.pose.bones, keyframe_types = ['location', 'rotation_quaternion']):
# verifica se existe apenas um bone
if (isinstance(pose_bones, int) or isinstance(pose_bones, str)):
# verifica se existe apenas um tipo de insercao de keyframe
if (isinstance(keyframe_types, str)):
bpy.context.object.pose.bones[pose_bones].keyframe_insert(index = -1, frame = current_frame, group = bpy.context.object.pose.bones[pose_bones].name, data_path = keyframe_types)
# verifica se existe mais de um tipo de insercao de keyframe
elif (isinstance(keyframe_types, list)):
for keyframe_type in keyframe_types:
bpy.context.object.pose.bones[bones].keyframe_insert(index = -1, frame = current_frame, group = bpy.context.object.pose.bones[pose_bones].name, data_path = keyframe_type)
# verifica se existe mais de um bone
elif (isinstance(pose_bones, list)):
for bone in pose_bones:
# verifica se existe apenas um tipo de insercao de keyframe
if (isinstance(keyframe_types, str)):
bpy.context.object.pose.bones[bone].keyframe_insert(index = -1, frame = current_frame, group = bpy.context.object.pose.bones[bone].name, data_path = keyframe_types)
# verifica se existe mais de um tipo de insercao de keyframe
elif (isinstance(keyframe_types, list)):
for keyframe_type in keyframe_types:
bpy.context.object.pose.bones[bone].keyframe_insert(index = -1, frame = current_frame, group = bpy.context.object.pose.bones[bone].name, data_path = keyframe_type)
return
# aplica biblioteca(s) de pose(s) e seu respectivo indice
def apply_pose(index = 0, pose_library = list(bpy.data.actions)):
# verifica se deve aplicar apenas uma biblioteca
if (isinstance(pose_library, int) or isinstance(pose_library, str)):
# verifica biblioteca fake_user
if (bpy.data.actions[pose_library].use_fake_user):
bpy.context.object.pose_library = bpy.data.actions[pose_library]
bpy.ops.poselib.apply_pose(pose_index = index)
# verifica se deve aplicar mais de uma biblioteca
elif (isinstance(pose_library, list)):
for library in pose_library:
# verifica biblioteca fake_user
if (library.use_fake_user):
bpy.context.object.pose_library = library
bpy.ops.poselib.apply_pose(pose_index = index)
bpy.context.object.pose_library = None
return
# consolida o movimento (faz insercao dos keyframes) e incrementa a timeline
def set_expression(timeline_facial, index, frame_duration = dict_duration['normal'], frame_transition = 0):
library_name = util.facial_expression_id
bones_facial = util.dict_bones[library_name]
util.select_bones(bones_facial)
# TODO separar bones 'location' e 'rotation_quaternion'
keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
apply_pose(index, library_name)
timeline_facial += frame_transition
keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
timeline_facial += frame_duration
keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
timeline_facial += frame_transition
util.deselect_bones(bones_facial)
return timeline_facial
# decodifica objeto JSON
def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_duration['normal']):
global dict_duration
global dict_transition
index = js_facial['expressao']
frame_duration = dict_duration[js_facial['duracao']]
frame_transition = dict_duration[js_facial['transicao']]
# insere o primeiro keyframe
if (timeline_facial == 0):
set_expression(timeline_facial, 0, initial_interpolation)
set_expression(timeline_facial, index, frame_duration, frame_transition)
set_expression(timeline_facial, 0, frame_duration)
return timeline_facial
"""
# unit test
def main():
import random
interpolation_start = 20
interpolation_end = 20
pose_max_range = round(bpy.data.actions[library_name].frame_range[1])
util.delete_all_keyframes()
apply_pose(0, library_name)
js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
#for i in range(0, pose_max_range + 1):
# js_facial = {"expressao": i, "transicao": 'normal', "duracao": 'normal'}
# print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
bpy.context.scene.frame_end = timeline_facial + interpolation_end
bpy.ops.screen.animation_play(reverse = False)
if __name__ == "__main__":
main()
"""