Commit bb4c6ded21679d1b5fece7e665174ed4a6414c1c

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

Implementa expressão facial dinâmica

Makefile
... ... @@ -7,7 +7,8 @@ JSON_ALL = \
7 7 { \
8 8 "facial": { \
9 9 "expressao": 0..21, \
10   - "velocidade": "lento|normal|rapido" \
  10 + "transicao": "lento|normal|rapido", \
  11 + "duracao": "lento|normal|rapido" \
11 12 }, \
12 13 "mao_esquerda": { \
13 14 "circular": { \
... ... @@ -102,28 +103,39 @@ JSON = \
102 103 '{ \
103 104 "userId": "lavid", \
104 105 "sinal": "Modelo JSON 2", \
105   - "ex_interpolacao": "lento|normal|rapido", \
106 106 "interpolacao": "normal", \
107 107 "movimentos": [ \
108 108 { \
109 109 "facial": { \
110   - "expressao": 21, \
111   - "velocidade": "lento|normal|rapido" \
  110 + "expressao": 20, \
  111 + "transicao": "normal", \
  112 + "duracao": "normal" \
112 113 }, \
113 114 "mao_esquerda": { \
114 115 "circular": { \
115 116 "plano": "esquerda-cima", \
116 117 "raio": "pequeno", \
117   - "velocidade": "lento", \
  118 + "velocidade": "normal", \
118 119 "lado_oposto": false, \
119 120 "sentido_inverso": false, \
120 121 "articulacao": 124, \
121   - "configuracao": 129, \
  122 + "configuracao": 60, \
122 123 "orientacao": 142 \
123 124 } \
124 125 }, \
125 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 }'
... ...
controller.py
... ... @@ -18,6 +18,6 @@ try:
18 18 # result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]], stdout = open('bpy.log', 'w'))
19 19 result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]])
20 20 except:
21   - result = pyutil.printStackTrace(__file__)
  21 + result = pyutil.print_stack_trace(__file__)
22 22  
23 23 exit(result)
... ...
facial.py 0 → 100644
... ... @@ -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 124 \ No newline at end of file
... ...
libras.py
... ... @@ -18,9 +18,16 @@ sys.path.insert(0, getcwd)
18 18 import util
19 19 import moves
20 20 import pyutil
  21 +import facial
21 22  
22 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 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 33 for obj in (pose_bones):
... ... @@ -41,17 +48,20 @@ def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions):
41 48  
42 49 def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular):
43 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 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 59 # diminuir a velocidade
50 60 if (js_movement['velocidade'] == 'lento'):
51   - periodo += 10
  61 + period += 10
52 62 # aumentar a velocidade
53 63 elif (js_movement['velocidade'] == 'rapido'):
54   - periodo -= 10
  64 + period -= 10
55 65 # definir eixos do movimento
56 66 if (js_movement['plano'] == 'frente-esquerda'):
57 67 x, y = 2, 0
... ... @@ -61,11 +71,11 @@ def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_righ
61 71 x, y = 0, 1
62 72 # mao usada (direita/esquerda)
63 73 if (is_right_hand):
64   - ik = bpy.context.object.pose.bones[1]
  74 + ik = bpy.context.object.pose.bones['ik_FK.R']
65 75 else:
66   - ik = bpy.context.object.pose.bones[0]
  76 + ik = bpy.context.object.pose.bones['ik_FK.L']
67 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 79 return current_frame
70 80  
71 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 89 current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True)
80 90 return current_frame + frame_jump
81 91  
  92 +"""
82 93 # Funcao responsavel por setar pose padrao
83 94 def poseDefault(json_input, positionFrames, collisionFlag = False):
84 95 handDefaultParam = [0, 0, 0]
85 96 util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag)
86 97 if(json_input["leftHand"] != []):
87 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 101 # Funcao responsavel por setar as configuracoes das maos
91 102 def setHandConfiguration(actions, handParam, positionFrames, bones):
... ... @@ -123,61 +134,66 @@ def configureHands(endFrame):
123 134 setHandConfiguration(actions[i], handParam, [endFrame], bones_[i])
124 135 elif(move == "contato"):
125 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 139 def main():
  140 + util.delete_all_keyframes()
134 141 util.configure_output()
135 142 bpy.context.scene.animation_data_create()
136 143  
137 144 try:
138 145 js_input = json.loads(sys.argv[6])
139 146 js_movimentos = js_input['movimentos']
140   - frame_jump = interpolation[js_input['interpolacao']]
  147 + frame_jump = dict_interpolation[js_input['interpolacao']]
141 148  
142 149 endFrame = pose_default(0)
143   - facial_frame = 0
144 150 mao_esquerda_frame = 0
145 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 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 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 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 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 191 endFrame += frame_jump
173 192  
174 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 197 #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo)
182 198 #poseDefault([1])
183 199 #configureHands(endFrame)
... ... @@ -187,7 +203,7 @@ def main():
187 203 util.render_sign(js_input["userId"], js_input["sinal"], endFrame)
188 204  
189 205 except:
190   - pyutil.printStackTrace(__file__)
  206 + pyutil.print_stack_trace(__file__)
191 207 raise
192 208  
193 209 if __name__ == "__main__":
... ...
pyutil.py
... ... @@ -64,7 +64,7 @@ def test_log():
64 64 # @def Função para exibir exceção
65 65 # @param string deve ser passado: "__file__" para identificar em qual arquivo ocorreu a exceção
66 66 # @return int Retorna 1
67   -def printStackTrace(fromFile):
  67 +def print_stack_trace(fromFile):
68 68 from sys import exc_info
69 69 from os.path import basename
70 70 error = "\n File name: %s\n Function name: %s\n Line code: %s\n Type exception: %s\n Message: %s" % (
... ...
util.py
... ... @@ -9,23 +9,33 @@ from bmesh_collision import bmesh_check_intersect_objects
9 9  
10 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 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 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 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 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 34 # define a posição dos keyframes
25   -hands_default_frames = [15]
  35 +# hands_default_frames = [15]
26 36  
27 37 # define a posição dos keyframes
28   -hands_frames_retilineo = [30, 33]
  38 +# hands_frames_retilineo = [30, 33]
29 39  
30 40 # Movimento coçar - Índices de poses
31 41 cocar_mao_aberta_index = 56
... ... @@ -33,7 +43,7 @@ cocar_mao_fechada_index = 24
33 43 cocar_orientation_index = 20
34 44  
35 45 # Action expressão facial
36   -facial_expression_id ='07_facial'
  46 +facial_expression_id = '07_facial'
37 47 facial_expression_action = [facial_expression_id]
38 48  
39 49 # Actions mão direita
... ... @@ -50,26 +60,39 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id]
50 60  
51 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 65 bpy.context.object.pose.bones[bones].bone.select = True
56   - else:
  66 + elif (isinstance(bones, list)):
57 67 for bone in bones:
58 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 76 bpy.context.object.pose.bones[bones].bone.select = False
63   - else:
  77 + elif (isinstance(bones, list)):
64 78 for bone in bones:
65 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 91 # Função responsável por selecionar as pose-libs e setar os frames
68 92 def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True):
69 93 bpy.ops.object.mode_set(mode = 'OBJECT')
70 94 bpy.ops.object.select_all(action="DESELECT")
71 95 bpy.ops.object.mode_set(mode = 'POSE')
72   -
73 96 for x in range(len(positionFrames)):
74 97 for l in range(len(actions)):
75 98 action = actions[l]
... ... @@ -80,7 +103,6 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True)
80 103 validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name
81 104 validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name
82 105 validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name
83   -
84 106 if (validHandConf or validPA or validO):
85 107 keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO)
86 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 112 keyframe_id = bone.name + "_" + path
91 113 last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0
92 114 last_keyframe_dict[keyframe_id] = positionFrame
93   -
94 115 if (rotationFlag and path == "rotation_quaternion"):
95 116 checkRotation(bone, positionFrame, last_keyframe)
96   -
97 117 if (collisionFlag):
98 118 checkCollision(bone, path, positionFrame, last_keyframe)
99 119  
... ... @@ -114,7 +134,6 @@ def checkRotation(bone, positionFrame, last_keyframe):
114 134 isRightHand = ".R" in bone.name
115 135 resetBnMaoPosition(isRightHand)
116 136 valid_rotation = validate_rotation(bone, positionFrame, last_keyframe)
117   -
118 137 if (not valid_rotation):
119 138 new_rotation = boneRQ.to_quaternion() * (-1)
120 139 bone.rotation_quaternion = new_rotation
... ... @@ -123,15 +142,12 @@ def checkRotation(bone, positionFrame, last_keyframe):
123 142 def checkCollision(bone, path, positionFrame, last_keyframe):
124 143 if (last_keyframe == positionFrame):
125 144 return
126   -
127 145 isRightHand = ".R" in bone.name
128 146 resetIKPosition(isRightHand)
129 147 handCollisionFrame = check_hand_collision(last_keyframe, positionFrame)
130   -
131 148 if (handCollisionFrame != -1):
132 149 handle_collision(bone, path, positionFrame, handCollisionFrame)
133 150 return
134   -
135 151 bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame)
136 152 if (bodyCollisionFrame != -1):
137 153 handle_collision(bone, path, positionFrame, bodyCollisionFrame)
... ... @@ -153,13 +169,12 @@ def check_collision(objName, otherObjName, initFrame, endFrame):
153 169 startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2))
154 170 collisionFrame = -1
155 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 178 scene.frame_set(frame_current)
164 179 return collisionFrame
165 180  
... ... @@ -169,15 +184,8 @@ def check_body_collision(isRightHand, initFrame, endFrame):
169 184 result = check_collision(hand_box, body_box, initFrame, endFrame)
170 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 187 # Função que define as configurações de saida
179 188 def configure_output():
180   - limpar_keyframes()
181 189 bpy.context.scene.frame_start = 0
182 190 bpy.context.scene.frame_current = bpy.context.scene.frame_start
183 191 bpy.context.scene.frame_end = bpy.context.scene.frame_start
... ... @@ -195,6 +203,7 @@ def configure_output():
195 203 bpy.context.scene.render.use_shadows = False
196 204 bpy.context.scene.render.tile_x = 320
197 205 bpy.context.scene.render.tile_y = 240
  206 + return
198 207  
199 208 def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end):
200 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 213 bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
205 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 215 bpy.ops.wm.quit_blender()
  216 + return
207 217  
208   -# descontinuada: get_endFrame
  218 +"""
209 219 def get_endFrame(json_input, hands_frames_retilineo):
210 220 endsFrame = [18]
211 221 if(json_input["rightHand"] != []):
... ... @@ -224,27 +234,24 @@ def get_endFrame(json_input, hands_frames_retilineo):
224 234 elif(json_input["rightHand"][0] == "retilineo"):
225 235 endsFrame.append(max(hands_frames_retilineo))
226 236 return(max(endsFrame))
  237 +"""
227 238  
228 239 def validate_rotation(bone, endFrame, startFrame = 0):
229 240 if (endFrame - startFrame == 1):
230 241 return True
231   -
232 242 rotFrames = [[]]
233 243 scene = bpy.context.scene
234 244 frame_current = scene.frame_current
235   -
236 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 249 rotFrames.remove([])
242 250 scene.frame_set(frame_current)
243   -
244 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 255 return True
249 256  
250 257 # Axis: "X", "Y" e "Z"
... ... @@ -252,6 +259,5 @@ def apply_rotation(bone, axis, currentFrame, endFrame, degree):
252 259 new_rotation = bone.rotation_quaternion.to_euler()
253 260 new_rotation.rotate_axis(axis, math.radians(degree))
254 261 new_rotation = new_rotation.to_quaternion()
255   -
256 262 bone.rotation_quaternion = new_rotation
257   - keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True)
258 263 \ No newline at end of file
  264 + keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True)
... ...