Commit bb4c6ded21679d1b5fece7e665174ed4a6414c1c

Authored by André Araújo
1 parent 8425c440
Exists in master

Implementa expressão facial dinâmica

@@ -7,7 +7,8 @@ JSON_ALL = \ @@ -7,7 +7,8 @@ JSON_ALL = \
7 { \ 7 { \
8 "facial": { \ 8 "facial": { \
9 "expressao": 0..21, \ 9 "expressao": 0..21, \
10 - "velocidade": "lento|normal|rapido" \ 10 + "transicao": "lento|normal|rapido", \
  11 + "duracao": "lento|normal|rapido" \
11 }, \ 12 }, \
12 "mao_esquerda": { \ 13 "mao_esquerda": { \
13 "circular": { \ 14 "circular": { \
@@ -102,28 +103,39 @@ JSON = \ @@ -102,28 +103,39 @@ JSON = \
102 '{ \ 103 '{ \
103 "userId": "lavid", \ 104 "userId": "lavid", \
104 "sinal": "Modelo JSON 2", \ 105 "sinal": "Modelo JSON 2", \
105 - "ex_interpolacao": "lento|normal|rapido", \  
106 "interpolacao": "normal", \ 106 "interpolacao": "normal", \
107 "movimentos": [ \ 107 "movimentos": [ \
108 { \ 108 { \
109 "facial": { \ 109 "facial": { \
110 - "expressao": 21, \  
111 - "velocidade": "lento|normal|rapido" \ 110 + "expressao": 20, \
  111 + "transicao": "normal", \
  112 + "duracao": "normal" \
112 }, \ 113 }, \
113 "mao_esquerda": { \ 114 "mao_esquerda": { \
114 "circular": { \ 115 "circular": { \
115 "plano": "esquerda-cima", \ 116 "plano": "esquerda-cima", \
116 "raio": "pequeno", \ 117 "raio": "pequeno", \
117 - "velocidade": "lento", \ 118 + "velocidade": "normal", \
118 "lado_oposto": false, \ 119 "lado_oposto": false, \
119 "sentido_inverso": false, \ 120 "sentido_inverso": false, \
120 "articulacao": 124, \ 121 "articulacao": 124, \
121 - "configuracao": 129, \ 122 + "configuracao": 60, \
122 "orientacao": 142 \ 123 "orientacao": 142 \
123 } \ 124 } \
124 }, \ 125 }, \
125 "mao_direita": { \ 126 "mao_direita": { \
126 } \ 127 } \
  128 + }, \
  129 + { \
  130 + "facial": { \
  131 + "expressao": 21, \
  132 + "transicao": "normal", \
  133 + "duracao": "normal" \
  134 + }, \
  135 + "mao_esquerda": { \
  136 + }, \
  137 + "mao_direita": { \
  138 + } \
127 } \ 139 } \
128 ] \ 140 ] \
129 }' 141 }'
@@ -18,6 +18,6 @@ try: @@ -18,6 +18,6 @@ try:
18 # result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]], stdout = open('bpy.log', 'w')) 18 # result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]], stdout = open('bpy.log', 'w'))
19 result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]]) 19 result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]])
20 except: 20 except:
21 - result = pyutil.printStackTrace(__file__) 21 + result = pyutil.print_stack_trace(__file__)
22 22
23 exit(result) 23 exit(result)
facial.py 0 → 100644
@@ -0,0 +1,123 @@ @@ -0,0 +1,123 @@
  1 +# -*- coding: UTF-8 -*-
  2 +
  3 +import bpy
  4 +import util
  5 +
  6 +library_name = '07_facial'
  7 +
  8 +# duracao na posicao selecionada
  9 +dict_duration = {
  10 + 'lento': 15,
  11 + 'normal': 10,
  12 + 'rapido': 5
  13 +}
  14 +
  15 +# tempo de entrada e saida na posicao selecionada
  16 +dict_transition = {
  17 + 'lento': 15,
  18 + 'normal': 10,
  19 + 'rapido': 5
  20 +}
  21 +
  22 +# marcador global da linha do tempo exclusivo para expressao facial
  23 +timeline_facial = 0
  24 +
  25 +# insere keyframes aos bones selecionados anteriormente e passados como parametro
  26 +def keyframe_insert(current_frame = 0, pose_bones = bpy.context.object.pose.bones, keyframe_types = ['location', 'rotation_quaternion']):
  27 + # verifica se existe apenas um bone
  28 + if (isinstance(pose_bones, int) or isinstance(pose_bones, str)):
  29 + # verifica se existe apenas um tipo de insercao de keyframe
  30 + if (isinstance(keyframe_types, str)):
  31 + 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)
  32 + # verifica se existe mais de um tipo de insercao de keyframe
  33 + elif (isinstance(keyframe_types, list)):
  34 + for keyframe_type in keyframe_types:
  35 + 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)
  36 + # verifica se existe mais de um bone
  37 + elif (isinstance(pose_bones, list)):
  38 + for bone in pose_bones:
  39 + # verifica se existe apenas um tipo de insercao de keyframe
  40 + if (isinstance(keyframe_types, str)):
  41 + 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)
  42 + # verifica se existe mais de um tipo de insercao de keyframe
  43 + elif (isinstance(keyframe_types, list)):
  44 + for keyframe_type in keyframe_types:
  45 + 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)
  46 + return
  47 +
  48 +# aplica biblioteca(s) de pose(s) e seu respectivo indice
  49 +def apply_pose(index = 0, pose_library = list(bpy.data.actions)):
  50 + # verifica se deve aplicar apenas uma biblioteca
  51 + if (isinstance(pose_library, int) or isinstance(pose_library, str)):
  52 + # verifica biblioteca fake_user
  53 + if (bpy.data.actions[pose_library].use_fake_user):
  54 + bpy.context.object.pose_library = bpy.data.actions[pose_library]
  55 + bpy.ops.poselib.apply_pose(pose_index = index)
  56 + # verifica se deve aplicar mais de uma biblioteca
  57 + elif (isinstance(pose_library, list)):
  58 + for library in pose_library:
  59 + # verifica biblioteca fake_user
  60 + if (library.use_fake_user):
  61 + bpy.context.object.pose_library = library
  62 + bpy.ops.poselib.apply_pose(pose_index = index)
  63 + bpy.context.object.pose_library = None
  64 + return
  65 +
  66 +# consolida o movimento (faz insercao dos keyframes) e incrementa a timeline
  67 +def set_expression(index, frame_duration = dict_duration['normal'], frame_transition = 0):
  68 + global timeline_facial
  69 + global library_name
  70 + bones_facial = util.dict_bones[library_name]
  71 + util.select_bones(bones_facial)
  72 + # TODO separar bones 'location' e 'rotation_quaternion'
  73 + keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
  74 + apply_pose(index, library_name)
  75 + timeline_facial += frame_transition
  76 + keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
  77 + timeline_facial += frame_duration
  78 + keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
  79 + timeline_facial += frame_transition
  80 + util.deselect_bones(bones_facial)
  81 + return timeline_facial
  82 +
  83 +# decodifica objeto JSON
  84 +def decode_expression(js_facial, initial_interpolation = dict_duration['normal']):
  85 + global dict_duration
  86 + global dict_transition
  87 + index = js_facial['expressao']
  88 + frame_duration = dict_duration[js_facial['duracao']]
  89 + frame_transition = dict_duration[js_facial['transicao']]
  90 + # insere o primeiro keyframe
  91 + if (timeline_facial == 0):
  92 + set_expression(0, initial_interpolation)
  93 + set_expression(index, frame_duration, frame_transition)
  94 + set_expression(0, frame_duration)
  95 + return timeline_facial
  96 +
  97 +"""
  98 +# unit test
  99 +def main():
  100 + import random
  101 + interpolation_start = 20
  102 + interpolation_end = 20
  103 + pose_max_range = round(bpy.data.actions[library_name].frame_range[1])
  104 +
  105 + util.delete_all_keyframes()
  106 + apply_pose(0, library_name)
  107 +
  108 + js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
  109 + print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
  110 +
  111 + js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
  112 + print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
  113 +
  114 + #for i in range(0, pose_max_range + 1):
  115 + # js_facial = {"expressao": i, "transicao": 'normal', "duracao": 'normal'}
  116 + # print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
  117 +
  118 + bpy.context.scene.frame_end = timeline_facial + interpolation_end
  119 + bpy.ops.screen.animation_play(reverse = False)
  120 +
  121 +if __name__ == "__main__":
  122 + main()
  123 +"""
0 \ No newline at end of file 124 \ No newline at end of file
@@ -18,9 +18,16 @@ sys.path.insert(0, getcwd) @@ -18,9 +18,16 @@ sys.path.insert(0, getcwd)
18 import util 18 import util
19 import moves 19 import moves
20 import pyutil 20 import pyutil
  21 +import facial
21 22
22 # intervalos de interpolacao dos keyframes 23 # intervalos de interpolacao dos keyframes
23 -interpolation = {'inicial': 20, 'lento': 5, 'normal': 10, 'rapido': 15, 'final': 20} 24 +dict_interpolation = {
  25 + 'inicial': 20,
  26 + 'lento': 5,
  27 + 'normal': 10,
  28 + 'rapido': 15,
  29 + 'final': 20
  30 +}
24 31
25 def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']): 32 def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']):
26 for obj in (pose_bones): 33 for obj in (pose_bones):
@@ -41,17 +48,20 @@ def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions): @@ -41,17 +48,20 @@ def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions):
41 48
42 def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular): 49 def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular):
43 # const 50 # const
44 - obj_raio = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5}  
45 - obj_periodo = {'lento': 55, 'normal': 45, 'rapido': 35} 51 + dict_ray = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5}
  52 + dict_period = {'lento': 55, 'normal': 45, 'rapido': 35}
46 # decodificar valores 53 # decodificar valores
47 - raio = obj_raio[js_movement['raio']]  
48 - periodo = obj_periodo[js_movement['velocidade']] 54 + ray = dict_ray[js_movement['raio']]
  55 + period = dict_period[js_movement['velocidade']]
  56 + print('setar articulacao:', js_movement['articulacao'])
  57 + print('setar configuracao:', js_movement['configuracao'])
  58 + print('setar orientacao:', js_movement['orientacao'])
49 # diminuir a velocidade 59 # diminuir a velocidade
50 if (js_movement['velocidade'] == 'lento'): 60 if (js_movement['velocidade'] == 'lento'):
51 - periodo += 10 61 + period += 10
52 # aumentar a velocidade 62 # aumentar a velocidade
53 elif (js_movement['velocidade'] == 'rapido'): 63 elif (js_movement['velocidade'] == 'rapido'):
54 - periodo -= 10 64 + period -= 10
55 # definir eixos do movimento 65 # definir eixos do movimento
56 if (js_movement['plano'] == 'frente-esquerda'): 66 if (js_movement['plano'] == 'frente-esquerda'):
57 x, y = 2, 0 67 x, y = 2, 0
@@ -61,11 +71,11 @@ def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_righ @@ -61,11 +71,11 @@ def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_righ
61 x, y = 0, 1 71 x, y = 0, 1
62 # mao usada (direita/esquerda) 72 # mao usada (direita/esquerda)
63 if (is_right_hand): 73 if (is_right_hand):
64 - ik = bpy.context.object.pose.bones[1] 74 + ik = bpy.context.object.pose.bones['ik_FK.R']
65 else: 75 else:
66 - ik = bpy.context.object.pose.bones[0] 76 + ik = bpy.context.object.pose.bones['ik_FK.L']
67 current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location']) 77 current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location'])
68 - current_frame = moves.circular(ik, current_frame + frame_jump, raio, periodo, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular) 78 + current_frame = moves.circular(ik, current_frame + frame_jump, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular)
69 return current_frame 79 return current_frame
70 80
71 def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand): 81 def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand):
@@ -79,13 +89,14 @@ def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand): @@ -79,13 +89,14 @@ def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand):
79 current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True) 89 current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True)
80 return current_frame + frame_jump 90 return current_frame + frame_jump
81 91
  92 +"""
82 # Funcao responsavel por setar pose padrao 93 # Funcao responsavel por setar pose padrao
83 def poseDefault(json_input, positionFrames, collisionFlag = False): 94 def poseDefault(json_input, positionFrames, collisionFlag = False):
84 handDefaultParam = [0, 0, 0] 95 handDefaultParam = [0, 0, 0]
85 util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag) 96 util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag)
86 if(json_input["leftHand"] != []): 97 if(json_input["leftHand"] != []):
87 util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag) 98 util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag)
88 - #setFaceConfiguration([0], positionFrames, util.faceBonesConf) 99 + setFaceConfiguration([0], positionFrames, util.faceBonesConf)
89 100
90 # Funcao responsavel por setar as configuracoes das maos 101 # Funcao responsavel por setar as configuracoes das maos
91 def setHandConfiguration(actions, handParam, positionFrames, bones): 102 def setHandConfiguration(actions, handParam, positionFrames, bones):
@@ -123,61 +134,66 @@ def configureHands(endFrame): @@ -123,61 +134,66 @@ def configureHands(endFrame):
123 setHandConfiguration(actions[i], handParam, [endFrame], bones_[i]) 134 setHandConfiguration(actions[i], handParam, [endFrame], bones_[i])
124 elif(move == "contato"): 135 elif(move == "contato"):
125 endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose) 136 endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose)
126 -  
127 -# Funcao que inicia a configuracao da face  
128 -def setFacialExpr(a, b):  
129 - pass  
130 - #if(json_input["facialExp"] != []):  
131 - # setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) 137 +"""
132 138
133 def main(): 139 def main():
  140 + util.delete_all_keyframes()
134 util.configure_output() 141 util.configure_output()
135 bpy.context.scene.animation_data_create() 142 bpy.context.scene.animation_data_create()
136 143
137 try: 144 try:
138 js_input = json.loads(sys.argv[6]) 145 js_input = json.loads(sys.argv[6])
139 js_movimentos = js_input['movimentos'] 146 js_movimentos = js_input['movimentos']
140 - frame_jump = interpolation[js_input['interpolacao']] 147 + frame_jump = dict_interpolation[js_input['interpolacao']]
141 148
142 endFrame = pose_default(0) 149 endFrame = pose_default(0)
143 - facial_frame = 0  
144 mao_esquerda_frame = 0 150 mao_esquerda_frame = 0
145 mao_direita_frame = 0 151 mao_direita_frame = 0
146 152
147 - # setar pose padrao inicial em todos os bones ('location' e 'rotation_quaternion')  
148 - endFrame += pose_default(interpolation['inicial']) 153 + # pose padrao inicial em todos os bones ('location' e 'rotation_quaternion')
  154 + endFrame += pose_default(dict_interpolation['inicial'])
149 155
150 for i in range(0, len(js_movimentos)): 156 for i in range(0, len(js_movimentos)):
151 -  
152 - js_facial = js_movimentos[i]['facial']  
153 -  
154 - if (js_facial != {}):  
155 - setFacialExpr(js_facial['expressao'], js_facial['velocidade']) 157 + # tenta decodificar objetos JSON
  158 + try:
  159 + js_facial = js_movimentos[i]['facial']
  160 + except:
  161 + js_facial = {}
  162 + try:
  163 + js_mao_esquerda = js_movimentos[i]['mao_esquerda']
  164 + except:
  165 + js_mao_esquerda = {}
  166 + try:
  167 + js_mao_direita = js_movimentos[i]['mao_direita']
  168 + except:
  169 + js_mao_direita = {}
  170 +
  171 + # faz tratamento dos objetos
  172 + if (js_facial == {}):
  173 + pyutil.log("<Vazio> js_movimentos[%d] >> Exp facial" % (i))
  174 + facial.set_expression(0, facial.timeline_facial + frame_jump)
156 else: 175 else:
157 - pyutil.log("<Vazio> Expressao Facial %d" % (i)) 176 + facial.decode_expression(js_facial)
158 177
159 - js_mao_esquerda = js_movimentos[i]['mao_esquerda']  
160 - if (js_mao_esquerda != {}):  
161 - mao_esquerda_frame += decode_hand_mov(mao_esquerda_frame, frame_jump, js_mao_esquerda, False) 178 + if (js_mao_esquerda == {}):
  179 + pyutil.log("<Vazio> js_movimentos[%d] >> Mao esquerda" % (i))
  180 + # TODO posicionar mao esquerda na lateral do corpo
162 else: 181 else:
163 - pyutil.log("<Vazio> mov %d Mao esquerda" % (i)) 182 + mao_esquerda_frame += decode_hand_mov(mao_esquerda_frame, frame_jump, js_mao_esquerda, False)
164 183
165 - js_mao_direita = js_movimentos[i]['mao_direita']  
166 - if (js_mao_direita != {}):  
167 - mao_direita_frame += decode_hand_mov(mao_direita_frame, frame_jump, js_mao_direita, True) 184 + if (js_mao_direita == {}):
  185 + pyutil.log("<Vazio> js_movimentos[%d] >> Mao direita" % (i))
  186 + # TODO posicionar mao direita na lateral do corpo
168 else: 187 else:
169 - pyutil.log("<Vazio> mov %d Mao direita" % (i)) 188 + mao_direita_frame += decode_hand_mov(mao_direita_frame, frame_jump, js_mao_direita, True)
170 189
171 - endFrame = max(facial_frame, mao_esquerda_frame, mao_direita_frame) 190 + endFrame = max(facial.timeline_facial, mao_esquerda_frame, mao_direita_frame)
172 endFrame += frame_jump 191 endFrame += frame_jump
173 192
174 # setar pose padrao final em todos os bones (location e rotation) 193 # setar pose padrao final em todos os bones (location e rotation)
175 - #endFrame += pose_default(endFrame + interpolation['final'])  
176 - endFrame = insert_keyframe_pose_default(endFrame, frame_jump)  
177 - endFrame += interpolation['final']  
178 -  
179 - # Sugestao: Alguma forma de uniformizar o calculo do endFrame (atualizado aqui e no movimento circular)  
180 - #initialFrame = 15 194 + #endFrame += pose_default(endFrame + dict_interpolation['final'])
  195 + #endFrame = insert_keyframe_pose_default(endFrame, frame_jump)
  196 + #endFrame += dict_interpolation['final']
181 #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo) 197 #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo)
182 #poseDefault([1]) 198 #poseDefault([1])
183 #configureHands(endFrame) 199 #configureHands(endFrame)
@@ -187,7 +203,7 @@ def main(): @@ -187,7 +203,7 @@ def main():
187 util.render_sign(js_input["userId"], js_input["sinal"], endFrame) 203 util.render_sign(js_input["userId"], js_input["sinal"], endFrame)
188 204
189 except: 205 except:
190 - pyutil.printStackTrace(__file__) 206 + pyutil.print_stack_trace(__file__)
191 raise 207 raise
192 208
193 if __name__ == "__main__": 209 if __name__ == "__main__":
@@ -64,7 +64,7 @@ def test_log(): @@ -64,7 +64,7 @@ def test_log():
64 # @def Função para exibir exceção 64 # @def Função para exibir exceção
65 # @param string deve ser passado: "__file__" para identificar em qual arquivo ocorreu a exceção 65 # @param string deve ser passado: "__file__" para identificar em qual arquivo ocorreu a exceção
66 # @return int Retorna 1 66 # @return int Retorna 1
67 -def printStackTrace(fromFile): 67 +def print_stack_trace(fromFile):
68 from sys import exc_info 68 from sys import exc_info
69 from os.path import basename 69 from os.path import basename
70 error = "\n File name: %s\n Function name: %s\n Line code: %s\n Type exception: %s\n Message: %s" % ( 70 error = "\n File name: %s\n Function name: %s\n Line code: %s\n Type exception: %s\n Message: %s" % (
@@ -9,23 +9,33 @@ from bmesh_collision import bmesh_check_intersect_objects @@ -9,23 +9,33 @@ from bmesh_collision import bmesh_check_intersect_objects
9 9
10 armature = bpy.context.scene.objects.get('Armature.001') 10 armature = bpy.context.scene.objects.get('Armature.001')
11 11
  12 +dict_bones = {
  13 + "01_conf_direita": ['BnDedo.1.R', 'BnDedo.1.R.006', 'BnDedo.1.R.005', 'BnDedo.1.R.001', 'BnDedo.1.R.008', 'BnDedo.1.R.007', 'BnDedo.1.R.002', 'BnDedo.1.R.010', 'BnDedo.1.R.009', 'BnDedo.1.R.003', 'BnDedo.1.R.012', 'BnDedo.1.R.011', 'BnDedo.1.R.004', 'BnDedo.1.R.014', 'BnDedo.1.R.013'],
  14 + "02_conf_esquerda": ['BnDedo.1.L', 'BnDedo.1.L.006', 'BnDedo.1.L.005', 'BnDedo.1.L.001', 'BnDedo.1.L.008', 'BnDedo.1.L.007', 'BnDedo.1.L.002', 'BnDedo.1.L.010', 'BnDedo.1.L.009', 'BnDedo.1.L.003', 'BnDedo.1.L.012', 'BnDedo.1.L.011', 'BnDedo.1.L.004', 'BnDedo.1.L.014', 'BnDedo.1.L.013'],
  15 + "03_pa_direita": ['ik_FK.R', 'BnPolyV.R'],
  16 + "04_pa_direita": ['ik_FK.R', 'BnPolyV.R'],
  17 + "05_orient_direita": ['BnMao.R'],
  18 + "06_orient_esquerda": ['BnMao.L'],
  19 + "07_facial": ['BnPescoco', 'BnCabeca', 'BnSobrancCentro.L', 'BnSobrancCentro.R', 'BnSobrancLateral.L', 'BnSobrancLateral.R', 'BnPalpebSuper.L', 'BnPalpebInfe.L', 'BnSobrancCentro', 'BnLabioCentroSuper', 'BnBochecha.L', 'BnBochecha.R', 'BnLabioCentroInfer', 'BnBocaCanto.L', 'BnBocaCanto.R', 'BnMandibula', 'BnLingua', 'BnLingua.003', 'BnLingua.001', 'BnLingua.002', 'BnPalpebSuper.R', 'BnPalpebInfe.R', 'BnOlhosMira', 'BnOlhoMira.L', 'BnOlhoMira.R', 'BnOlho.L', 'BnOlho.R']
  20 +}
  21 +
12 # Vetor com indices de cada bone do lado direito 22 # Vetor com indices de cada bone do lado direito
13 -rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66] 23 +# rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66]
14 24
15 # Vetor com indices de cada bone do lado esquerdo 25 # Vetor com indices de cada bone do lado esquerdo
16 -leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] 26 +# leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82]
17 27
18 # Vetor com indices de cada bone da face 28 # Vetor com indices de cada bone da face
19 -faceBonesConf = [15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47] 29 +# faceBonesConf = [15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47]
20 30
21 # Vetor com indices de todos os bones 31 # Vetor com indices de todos os bones
22 -allBones = list(range(len(armature.pose.bones))) 32 +# allBones = list(range(len(armature.pose.bones)))
23 33
24 # define a posição dos keyframes 34 # define a posição dos keyframes
25 -hands_default_frames = [15] 35 +# hands_default_frames = [15]
26 36
27 # define a posição dos keyframes 37 # define a posição dos keyframes
28 -hands_frames_retilineo = [30, 33] 38 +# hands_frames_retilineo = [30, 33]
29 39
30 # Movimento coçar - Índices de poses 40 # Movimento coçar - Índices de poses
31 cocar_mao_aberta_index = 56 41 cocar_mao_aberta_index = 56
@@ -33,7 +43,7 @@ cocar_mao_fechada_index = 24 @@ -33,7 +43,7 @@ cocar_mao_fechada_index = 24
33 cocar_orientation_index = 20 43 cocar_orientation_index = 20
34 44
35 # Action expressão facial 45 # Action expressão facial
36 -facial_expression_id ='07_facial' 46 +facial_expression_id = '07_facial'
37 facial_expression_action = [facial_expression_id] 47 facial_expression_action = [facial_expression_id]
38 48
39 # Actions mão direita 49 # Actions mão direita
@@ -50,26 +60,39 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id] @@ -50,26 +60,39 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id]
50 60
51 last_keyframe_dict = {} 61 last_keyframe_dict = {}
52 62
53 -def select_bones(bones = None):  
54 - if (isinstance(bones, int)): 63 +def select_bones(bones = bpy.context.object.pose.bones):
  64 + if (isinstance(bones, int) or isinstance(bones, str)):
55 bpy.context.object.pose.bones[bones].bone.select = True 65 bpy.context.object.pose.bones[bones].bone.select = True
56 - else: 66 + elif (isinstance(bones, list)):
57 for bone in bones: 67 for bone in bones:
58 bpy.context.object.pose.bones[bone].bone.select = True 68 bpy.context.object.pose.bones[bone].bone.select = True
  69 + elif (isinstance(bones, type(bpy.context.object.pose.bones))):
  70 + for pose_bone in bones:
  71 + pose_bone.bone.select = True
  72 + return
59 73
60 -def deselect_bones(bones = None):  
61 - if (isinstance(bones, int)): 74 +def deselect_bones(bones = bpy.context.object.pose.bones):
  75 + if (isinstance(bones, int) or isinstance(bones, str)):
62 bpy.context.object.pose.bones[bones].bone.select = False 76 bpy.context.object.pose.bones[bones].bone.select = False
63 - else: 77 + elif (isinstance(bones, list)):
64 for bone in bones: 78 for bone in bones:
65 bpy.context.object.pose.bones[bone].bone.select = False 79 bpy.context.object.pose.bones[bone].bone.select = False
  80 + elif (isinstance(bones, type(bpy.context.object.pose.bones))):
  81 + for pose_bone in bones:
  82 + pose_bone.bone.select = False
  83 + return
  84 +
  85 +def delete_all_keyframes():
  86 + bpy.context.active_object.animation_data_clear()
  87 + for obj in bpy.data.objects:
  88 + obj.animation_data_clear()
  89 + return
66 90
67 # Função responsável por selecionar as pose-libs e setar os frames 91 # Função responsável por selecionar as pose-libs e setar os frames
68 def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True): 92 def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True):
69 bpy.ops.object.mode_set(mode = 'OBJECT') 93 bpy.ops.object.mode_set(mode = 'OBJECT')
70 bpy.ops.object.select_all(action="DESELECT") 94 bpy.ops.object.select_all(action="DESELECT")
71 bpy.ops.object.mode_set(mode = 'POSE') 95 bpy.ops.object.mode_set(mode = 'POSE')
72 -  
73 for x in range(len(positionFrames)): 96 for x in range(len(positionFrames)):
74 for l in range(len(actions)): 97 for l in range(len(actions)):
75 action = actions[l] 98 action = actions[l]
@@ -80,7 +103,6 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) @@ -80,7 +103,6 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True)
80 validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name 103 validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name
81 validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name 104 validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name
82 validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name 105 validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name
83 -  
84 if (validHandConf or validPA or validO): 106 if (validHandConf or validPA or validO):
85 keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO) 107 keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO)
86 keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) 108 keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO)
@@ -90,10 +112,8 @@ def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFla @@ -90,10 +112,8 @@ def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFla
90 keyframe_id = bone.name + "_" + path 112 keyframe_id = bone.name + "_" + path
91 last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 113 last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0
92 last_keyframe_dict[keyframe_id] = positionFrame 114 last_keyframe_dict[keyframe_id] = positionFrame
93 -  
94 if (rotationFlag and path == "rotation_quaternion"): 115 if (rotationFlag and path == "rotation_quaternion"):
95 checkRotation(bone, positionFrame, last_keyframe) 116 checkRotation(bone, positionFrame, last_keyframe)
96 -  
97 if (collisionFlag): 117 if (collisionFlag):
98 checkCollision(bone, path, positionFrame, last_keyframe) 118 checkCollision(bone, path, positionFrame, last_keyframe)
99 119
@@ -114,7 +134,6 @@ def checkRotation(bone, positionFrame, last_keyframe): @@ -114,7 +134,6 @@ def checkRotation(bone, positionFrame, last_keyframe):
114 isRightHand = ".R" in bone.name 134 isRightHand = ".R" in bone.name
115 resetBnMaoPosition(isRightHand) 135 resetBnMaoPosition(isRightHand)
116 valid_rotation = validate_rotation(bone, positionFrame, last_keyframe) 136 valid_rotation = validate_rotation(bone, positionFrame, last_keyframe)
117 -  
118 if (not valid_rotation): 137 if (not valid_rotation):
119 new_rotation = boneRQ.to_quaternion() * (-1) 138 new_rotation = boneRQ.to_quaternion() * (-1)
120 bone.rotation_quaternion = new_rotation 139 bone.rotation_quaternion = new_rotation
@@ -123,15 +142,12 @@ def checkRotation(bone, positionFrame, last_keyframe): @@ -123,15 +142,12 @@ def checkRotation(bone, positionFrame, last_keyframe):
123 def checkCollision(bone, path, positionFrame, last_keyframe): 142 def checkCollision(bone, path, positionFrame, last_keyframe):
124 if (last_keyframe == positionFrame): 143 if (last_keyframe == positionFrame):
125 return 144 return
126 -  
127 isRightHand = ".R" in bone.name 145 isRightHand = ".R" in bone.name
128 resetIKPosition(isRightHand) 146 resetIKPosition(isRightHand)
129 handCollisionFrame = check_hand_collision(last_keyframe, positionFrame) 147 handCollisionFrame = check_hand_collision(last_keyframe, positionFrame)
130 -  
131 if (handCollisionFrame != -1): 148 if (handCollisionFrame != -1):
132 handle_collision(bone, path, positionFrame, handCollisionFrame) 149 handle_collision(bone, path, positionFrame, handCollisionFrame)
133 return 150 return
134 -  
135 bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame) 151 bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame)
136 if (bodyCollisionFrame != -1): 152 if (bodyCollisionFrame != -1):
137 handle_collision(bone, path, positionFrame, bodyCollisionFrame) 153 handle_collision(bone, path, positionFrame, bodyCollisionFrame)
@@ -153,13 +169,12 @@ def check_collision(objName, otherObjName, initFrame, endFrame): @@ -153,13 +169,12 @@ def check_collision(objName, otherObjName, initFrame, endFrame):
153 startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) 169 startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2))
154 collisionFrame = -1 170 collisionFrame = -1
155 for i in range(startFrame, endFrame + 1, 1): 171 for i in range(startFrame, endFrame + 1, 1):
156 - scene.frame_set(i)  
157 - obj = scene.objects.get(objName)  
158 - otherObj = scene.objects.get(otherObjName)  
159 -  
160 - if (bmesh_check_intersect_objects(obj, otherObj)):  
161 - collisionFrame = i  
162 - break 172 + scene.frame_set(i)
  173 + obj = scene.objects.get(objName)
  174 + otherObj = scene.objects.get(otherObjName)
  175 + if (bmesh_check_intersect_objects(obj, otherObj)):
  176 + collisionFrame = i
  177 + break
163 scene.frame_set(frame_current) 178 scene.frame_set(frame_current)
164 return collisionFrame 179 return collisionFrame
165 180
@@ -169,15 +184,8 @@ def check_body_collision(isRightHand, initFrame, endFrame): @@ -169,15 +184,8 @@ def check_body_collision(isRightHand, initFrame, endFrame):
169 result = check_collision(hand_box, body_box, initFrame, endFrame) 184 result = check_collision(hand_box, body_box, initFrame, endFrame)
170 return result 185 return result
171 186
172 -# Função que limpa todos os keyframes e define a quantidade de frames  
173 -def limpar_keyframes():  
174 - bpy.context.active_object.animation_data_clear()  
175 - for i in bpy.data.objects:  
176 - i.animation_data_clear()  
177 -  
178 # Função que define as configurações de saida 187 # Função que define as configurações de saida
179 def configure_output(): 188 def configure_output():
180 - limpar_keyframes()  
181 bpy.context.scene.frame_start = 0 189 bpy.context.scene.frame_start = 0
182 bpy.context.scene.frame_current = bpy.context.scene.frame_start 190 bpy.context.scene.frame_current = bpy.context.scene.frame_start
183 bpy.context.scene.frame_end = bpy.context.scene.frame_start 191 bpy.context.scene.frame_end = bpy.context.scene.frame_start
@@ -195,6 +203,7 @@ def configure_output(): @@ -195,6 +203,7 @@ def configure_output():
195 bpy.context.scene.render.use_shadows = False 203 bpy.context.scene.render.use_shadows = False
196 bpy.context.scene.render.tile_x = 320 204 bpy.context.scene.render.tile_x = 320
197 bpy.context.scene.render.tile_y = 240 205 bpy.context.scene.render.tile_y = 240
  206 + return
198 207
199 def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end): 208 def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end):
200 getcwd = os.path.dirname(os.path.abspath(__file__)) 209 getcwd = os.path.dirname(os.path.abspath(__file__))
@@ -204,8 +213,9 @@ def render_sign(user_id, nome_sinal = &quot;sinal&quot;, frame_final = bpy.context.scene.f @@ -204,8 +213,9 @@ def render_sign(user_id, nome_sinal = &quot;sinal&quot;, frame_final = bpy.context.scene.f
204 bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "") 213 bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
205 pyutil.file_rename("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end)) 214 pyutil.file_rename("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end))
206 bpy.ops.wm.quit_blender() 215 bpy.ops.wm.quit_blender()
  216 + return
207 217
208 -# descontinuada: get_endFrame 218 +"""
209 def get_endFrame(json_input, hands_frames_retilineo): 219 def get_endFrame(json_input, hands_frames_retilineo):
210 endsFrame = [18] 220 endsFrame = [18]
211 if(json_input["rightHand"] != []): 221 if(json_input["rightHand"] != []):
@@ -224,27 +234,24 @@ def get_endFrame(json_input, hands_frames_retilineo): @@ -224,27 +234,24 @@ def get_endFrame(json_input, hands_frames_retilineo):
224 elif(json_input["rightHand"][0] == "retilineo"): 234 elif(json_input["rightHand"][0] == "retilineo"):
225 endsFrame.append(max(hands_frames_retilineo)) 235 endsFrame.append(max(hands_frames_retilineo))
226 return(max(endsFrame)) 236 return(max(endsFrame))
  237 +"""
227 238
228 def validate_rotation(bone, endFrame, startFrame = 0): 239 def validate_rotation(bone, endFrame, startFrame = 0):
229 if (endFrame - startFrame == 1): 240 if (endFrame - startFrame == 1):
230 return True 241 return True
231 -  
232 rotFrames = [[]] 242 rotFrames = [[]]
233 scene = bpy.context.scene 243 scene = bpy.context.scene
234 frame_current = scene.frame_current 244 frame_current = scene.frame_current
235 -  
236 for i in range(startFrame+1, endFrame+1, 1): 245 for i in range(startFrame+1, endFrame+1, 1):
237 - scene.frame_set(i)  
238 - rotFrames[-1] = bone.rotation_quaternion.to_euler()  
239 - rotFrames.append([])  
240 - 246 + scene.frame_set(i)
  247 + rotFrames[-1] = bone.rotation_quaternion.to_euler()
  248 + rotFrames.append([])
241 rotFrames.remove([]) 249 rotFrames.remove([])
242 scene.frame_set(frame_current) 250 scene.frame_set(frame_current)
243 -  
244 for k in range(1, len(rotFrames), 1): 251 for k in range(1, len(rotFrames), 1):
245 - for i in range(0, 3, 1):  
246 - if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/2:  
247 - return False 252 + for i in range(0, 3, 1):
  253 + if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/2:
  254 + return False
248 return True 255 return True
249 256
250 # Axis: "X", "Y" e "Z" 257 # Axis: "X", "Y" e "Z"
@@ -252,6 +259,5 @@ def apply_rotation(bone, axis, currentFrame, endFrame, degree): @@ -252,6 +259,5 @@ def apply_rotation(bone, axis, currentFrame, endFrame, degree):
252 new_rotation = bone.rotation_quaternion.to_euler() 259 new_rotation = bone.rotation_quaternion.to_euler()
253 new_rotation.rotate_axis(axis, math.radians(degree)) 260 new_rotation.rotate_axis(axis, math.radians(degree))
254 new_rotation = new_rotation.to_quaternion() 261 new_rotation = new_rotation.to_quaternion()
255 -  
256 bone.rotation_quaternion = new_rotation 262 bone.rotation_quaternion = new_rotation
257 - keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True)  
258 \ No newline at end of file 263 \ No newline at end of file
  264 + keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True)