Commit e313bcb0251531f63b4c31711c70355bbafcbeea

Authored by André Araújo
1 parent 42f9b71d
Exists in master

Atualiza movimento Circular, Helicoidal, Facial

Makefile
1   -JSON = $(JSON_RETILINEO)
  1 +JSON = $(JSON_CIRCULAR)
2 2  
3 3 # ----------------------------
4   -# JSON = $(JSON_CIRCULAR)
5   -# JSON = $(JSON_CONTATO_ALISAR)
6   -# JSON = $(JSON_CONTATO_COCAR)
7   -# JSON = $(JSON_CONTATO_TOCAR)
8   -# JSON = $(JSON_CONTATO_RISCAR)
9   -# JSON = $(JSON_FACIAL)
10   -# JSON = $(JSON_HELICOIDAL)
11   -# JSON = $(JSON_PONTUAL)
12   -# JSON = $(JSON_RETILINEO)
13   -# JSON = $(JSON_SEMI_CIRCULAR)
14   -# JSON = $(JSON_SENOIDAL)
  4 +# JSON = $(JSON_CIRCULAR) [OK]
  5 +# JSON = $(JSON_CONTATO_ALISAR) [--]
  6 +# JSON = $(JSON_CONTATO_COCAR) [--]
  7 +# JSON = $(JSON_CONTATO_TOCAR) [--]
  8 +# JSON = $(JSON_CONTATO_RISCAR) [--]
  9 +# JSON = $(JSON_FACIAL) [OK]
  10 +# JSON = $(JSON_HELICOIDAL) [OK]
  11 +# JSON = $(JSON_PONTUAL) [OK]
  12 +# JSON = $(JSON_RETILINEO) [OK]
  13 +# JSON = $(JSON_SEMICIRCULAR) [OK]
  14 +# JSON = $(JSON_SENOIDAL) [OK]
15 15 # ----------------------------
16 16  
17 17 JSON_CIRCULAR = \
... ... @@ -22,7 +22,8 @@ JSON_CIRCULAR = \
22 22 "movimentos": [ \
23 23 { \
24 24 "facial": {}, \
25   - "mao_esquerda": { \
  25 + "mao_esquerda": {}, \
  26 + "mao_direita": { \
26 27 "circular": { \
27 28 "plano": "esquerda-cima", \
28 29 "raio": "pequeno", \
... ... @@ -30,11 +31,10 @@ JSON_CIRCULAR = \
30 31 "lado_oposto": false, \
31 32 "sentido_inverso": false, \
32 33 "articulacao": 80, \
33   - "configuracao": 10, \
34   - "orientacao": 20 \
  34 + "configuracao": 15, \
  35 + "orientacao": 18 \
35 36 } \
36   - }, \
37   - "mao_direita": {} \
  37 + } \
38 38 } \
39 39 ] \
40 40 }'
... ... @@ -47,7 +47,8 @@ JSON_CONTATO_ALISAR = \
47 47 "movimentos": [ \
48 48 { \
49 49 "facial": {}, \
50   - "mao_direita": { \
  50 + "mao_direita": {}, \
  51 + "mao_esquerda": { \
51 52 "contato": { \
52 53 "movimento_orientacao": "paralelo", \
53 54 "alisar": { \
... ... @@ -56,8 +57,7 @@ JSON_CONTATO_ALISAR = \
56 57 "orientacao": 11 \
57 58 } \
58 59 } \
59   - }, \
60   - "mao_esquerda": {} \
  60 + } \
61 61 } \
62 62 ] \
63 63 }'
... ... @@ -70,7 +70,8 @@ JSON_CONTATO_COCAR = \
70 70 "movimentos": [ \
71 71 { \
72 72 "facial": {}, \
73   - "mao_direita": { \
  73 + "mao_direita": {}, \
  74 + "mao_esquerda": { \
74 75 "contato": { \
75 76 "cocar": { \
76 77 "articulacao": 71, \
... ... @@ -78,8 +79,7 @@ JSON_CONTATO_COCAR = \
78 79 "orientacao": 11 \
79 80 } \
80 81 } \
81   - }, \
82   - "mao_esquerda": {} \
  82 + } \
83 83 } \
84 84 ] \
85 85 }'
... ... @@ -92,7 +92,8 @@ JSON_CONTATO_TOCAR = \
92 92 "movimentos": [ \
93 93 { \
94 94 "facial": {}, \
95   - "mao_direita": { \
  95 + "mao_direita": {}, \
  96 + "mao_esquerda": {}, \
96 97 "contato": { \
97 98 "tocar": { \
98 99 "articulacao": 71, \
... ... @@ -100,8 +101,7 @@ JSON_CONTATO_TOCAR = \
100 101 "orientacao": 11 \
101 102 } \
102 103 } \
103   - }, \
104   - "mao_esquerda": {} \
  104 + } \
105 105 } \
106 106 ] \
107 107 }'
... ... @@ -114,7 +114,8 @@ JSON_CONTATO_RISCAR = \
114 114 "movimentos": [ \
115 115 { \
116 116 "facial": {}, \
117   - "mao_direita": { \
  117 + "mao_direita": {}, \
  118 + "mao_esquerda": { \
118 119 "contato": { \
119 120 "riscar": { \
120 121 "articulacao": 71, \
... ... @@ -122,8 +123,7 @@ JSON_CONTATO_RISCAR = \
122 123 "orientacao": 11 \
123 124 } \
124 125 } \
125   - }, \
126   - "mao_esquerda": {} \
  126 + } \
127 127 } \
128 128 ] \
129 129 }'
... ... @@ -135,22 +135,28 @@ JSON_FACIAL = \
135 135 "interpolacao": "normal", \
136 136 "movimentos": [ \
137 137 { \
  138 + "mao_direita": {}, \
  139 + "mao_esquerda": {}, \
138 140 "facial": { \
139 141 "expressao": 10, \
140 142 "transicao": "normal", \
141 143 "duracao": "normal" \
142   - }, \
  144 + } \
  145 + }, \
  146 + { \
143 147 "mao_direita": {}, \
144   - "mao_esquerda": {} \
  148 + "mao_esquerda": {}, \
  149 + "facial": { \
  150 + } \
145 151 }, \
146 152 { \
  153 + "mao_direita": {}, \
  154 + "mao_esquerda": {}, \
147 155 "facial": { \
148 156 "expressao": 11, \
149 157 "transicao": "normal", \
150 158 "duracao": "normal" \
151 159 } \
152   - "mao_direita": {}, \
153   - "mao_esquerda": {} \
154 160 } \
155 161 ] \
156 162 }'
... ... @@ -163,20 +169,21 @@ JSON_HELICOIDAL = \
163 169 "movimentos": [ \
164 170 { \
165 171 "facial": {}, \
166   - "mao_esquerda": { \
  172 + "mao_esquerda": {}, \
  173 + "mao_direita": { \
167 174 "helicoidal": { \
168 175 "plano": "esquerda-cima", \
169 176 "raio": "pequeno", \
170 177 "velocidade": "normal", \
171 178 "lado_oposto": false, \
172   - "sentido_inverso": false, \
173   - "articulacao": 80, \
174   - "configuracao": 10, \
175   - "orientacao": 20 \
  179 + "sentido_inverso": true, \
  180 + "articulacao": 79, \
  181 + "configuracao": 0, \
  182 + "orientacao": 64 \
176 183 } \
177   - }, \
178   - "mao_direita": {} \
  184 + } \
179 185 } \
  186 + ] \
180 187 }'
181 188  
182 189 JSON_PONTUAL = \
... ... @@ -187,14 +194,13 @@ JSON_PONTUAL = \
187 194 "movimentos": [ \
188 195 { \
189 196 "facial": {}, \
190   - "mao_direita": { \
  197 + "mao_direita": {}, \
  198 + "mao_esquerda": { \
191 199 "pontual": { \
192 200 "articulacao": 71, \
193 201 "configuracao": 19, \
194 202 "orientacao": 11 \
195 203 } \
196   - }, \
197   - "mao_esquerda": { \
198 204 } \
199 205 } \
200 206 ] \
... ... @@ -208,41 +214,42 @@ JSON_RETILINEO = \
208 214 "movimentos": [ \
209 215 { \
210 216 "facial": {}, \
211   - "mao_direita": { \
  217 + "mao_direita": {}, \
  218 + "mao_esquerda": { \
212 219 "retilineo": { \
213 220 "articulacao_inicial": 71, \
214   - "articulacao_final": 75, \
215   - "configuracao": 19, \
216   - "orientacao": 11 \
  221 + "configuracao_inicial": 19, \
  222 + "orientacao_inicial": 11, \
  223 + "articulacao_final": 78, \
  224 + "configuracao_final": 19, \
  225 + "orientacao_final": 11 \
217 226 } \
218   - }, \
219   - "mao_esquerda": { \
220 227 } \
221 228 } \
222 229 ] \
223 230 }'
224 231  
225   -JSON_SEMI_CIRCULAR = \
  232 +JSON_SEMICIRCULAR = \
226 233 '{ \
227 234 "userId": "lavid", \
228   - "sinal": "modelo_semi_circular", \
  235 + "sinal": "modelo_semicircular", \
229 236 "interpolacao": "normal", \
230 237 "movimentos": [ \
231 238 { \
232 239 "facial": {}, \
233   - "mao_esquerda": { \
234   - "circular": { \
  240 + "mao_esquerda": {}, \
  241 + "mao_direita": { \
  242 + "semicircular": { \
235 243 "plano": "esquerda-cima", \
236 244 "raio": "pequeno", \
237 245 "velocidade": "normal", \
238 246 "lado_oposto": false, \
239 247 "sentido_inverso": false, \
240 248 "articulacao": 80, \
241   - "configuracao": 10, \
242   - "orientacao": 20 \
  249 + "configuracao": 15, \
  250 + "orientacao": 18 \
243 251 } \
244   - }, \
245   - "mao_direita": {} \
  252 + } \
246 253 } \
247 254 ] \
248 255 }'
... ... @@ -254,26 +261,22 @@ JSON_SENOIDAL = \
254 261 "interpolacao": "normal", \
255 262 "movimentos": [ \
256 263 { \
257   - "facial": { \
258   - "expressao": 10, \
259   - "transicao": "normal", \
260   - "duracao": "normal" \
261   - }, \
262   - "mao_esquerda": { \
  264 + "facial": {}, \
  265 + "mao_esquerda": {}, \
  266 + "mao_direita": { \
263 267 "circular": { \
264 268 "plano": "esquerda-cima", \
265 269 "raio": "pequeno", \
266 270 "velocidade": "normal", \
267 271 "lado_oposto": false, \
268 272 "sentido_inverso": false, \
269   - "articulacao": 80, \
270   - "configuracao": 10, \
271   - "orientacao": 20 \
  273 + "articulacao": 79, \
  274 + "configuracao": 0, \
  275 + "orientacao": 64 \
272 276 } \
273   - }, \
274   - "mao_direita": { \
275 277 } \
276 278 } \
  279 + ] \
277 280 }'
278 281  
279 282 BLEND = avatar_cartoon_v2.74.blend
... ...
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.print_stack_trace(__file__)
  21 + result = pyutil.print_stack_trace()
22 22  
23 23 exit(result)
... ...
decode.py
... ... @@ -2,81 +2,33 @@ import bpy
2 2 import moves
3 3 import util
4 4  
5   -def circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular):
6   - dict_ray = {
7   - 'pequeno': 0.5,
8   - 'normal': 1.0,
9   - 'grande': 1.5
10   - }
11   - dict_period = {
12   - 'lento': 55,
13   - 'normal': 45,
14   - 'rapido': 35
15   - }
16   - # decodificar valores
17   - ray = dict_ray[js_movement['raio']]
18   - period = dict_period[js_movement['velocidade']]
19   - # diminuir a velocidade
20   - if (js_movement['velocidade'] == 'lento'):
21   - period += 10
22   - # aumentar a velocidade
23   - elif (js_movement['velocidade'] == 'rapido'):
24   - period -= 10
25   - # definir eixos do movimento
26   - if (js_movement['plano'] == 'frente-esquerda'):
27   - x, y = 2, 0
28   - elif (js_movement['plano'] == 'frente-cima'):
29   - x, y = 2, 1
30   - else:
31   - x, y = 0, 1
32   - # mao usada (direita/esquerda)
33   - if (is_right_hand):
34   - ik = bpy.context.object.pose.bones['ik_FK.R']
35   - else:
36   - ik = bpy.context.object.pose.bones['ik_FK.L']
37   - #current_frame = insert_keyframe_pose_default(current_frame, [ik], ['location'])
38   - current_frame = moves.circular(ik, current_frame, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular)
39   - return current_frame
  5 +def facial(js_facial, current_frame, frame_jump):
  6 + return moves.facial(js_facial, current_frame, frame_jump)
40 7  
41 8 def contato(js_movement, current_frame, frame_jump, is_right_hand):
42 9 sub_type = next(iter(js_movement.keys()))
43 10 mov_param = js_movement[sub_type]
44 11 action = util.right_hand_actions if is_right_hand else util.left_hand_actions
45 12 bones = util.right_bones_conf if is_right_hand else util.left_bones_conf
46   - current_frame = current_frame + 2*frame_jump
  13 + current_frame = current_frame + (2 * frame_jump)
47 14 return moves.contato(action, sub_type, mov_param, bones, is_right_hand, current_frame, frame_jump)
48 15  
49   -def helicoidal(js_movement, current_frame, frame_jump, is_right_hand):
50   - return moves.helicoidal(js_movement, current_frame, frame_jump, is_right_hand)
51   -
52   -def pontual(js_movement, current_frame, frame_jump, is_right_hand):
53   - return moves.pontual(js_movement, current_frame, frame_jump, is_right_hand)
54   -
55   -def retilineo(js_movement, current_frame, frame_jump, is_right_hand):
56   - return moves.retilineo(js_movement, current_frame, frame_jump, is_right_hand)
57   -
58   -def semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular):
59   - return moves.semi_circular(js_movement, current_frame, frame_jump, is_right_hand)
60   -
61   -def senoidal(js_movement, current_frame, frame_jump, is_right_hand):
62   - return moves.senoidal(js_movement, current_frame, frame_jump, is_right_hand)
63   -
64 16 def hand_mov(current_frame, frame_jump, js_mao, is_right_hand):
65 17 if (js_mao == {}):
66   - return current_frame
  18 + return current_frame + (2 * frame_jump)
67 19 movement_name = next(iter(js_mao.keys()))
68   - if (movement_name == 'circular'):
69   - current_frame = circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, False)
70   - elif (movement_name == 'semicircular'):
71   - current_frame = circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True)
72   - elif (movement_name == 'contato'):
  20 + if (movement_name == "circular"):
  21 + current_frame = moves.circular(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  22 + elif (movement_name == "semicircular"):
  23 + current_frame = moves.semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  24 + elif (movement_name == "contato"):
73 25 current_frame = contato(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
74   - elif (movement_name == 'helicoidal'):
75   - current_frame = espiral(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
76   - elif (movement_name == 'pontual'):
77   - current_frame = pontual(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
78   - elif (movement_name == 'retilineo'):
79   - current_frame = retilineo(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
80   - elif (movement_name == 'senoidal'):
81   - current_frame = senoidal(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  26 + elif (movement_name == "helicoidal"):
  27 + current_frame = moves.helicoidal(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  28 + elif (movement_name == "pontual"):
  29 + current_frame = moves.pontual(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  30 + elif (movement_name == "retilineo"):
  31 + current_frame = moves.retilineo(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  32 + elif (movement_name == "senoidal"):
  33 + current_frame = moves.senoidal(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
82 34 return current_frame + frame_jump
... ...
facial.py
... ... @@ -1,113 +0,0 @@
1   -# -*- coding: UTF-8 -*-
2   -
3   -import bpy
4   -import util
5   -
6   -# duracao na posicao selecionada
7   -dict_duration = {
8   - 'inicial': 10,
9   - 'lento': 15,
10   - 'normal': 10,
11   - 'rapido': 5,
12   - 'final': 10,
13   -}
14   -
15   -# tempo de entrada e saida na posicao selecionada
16   -dict_transition = {
17   - 'inicial': 0,
18   - 'lento': 15,
19   - 'normal': 10,
20   - 'rapido': 5
21   -}
22   -
23   -# insere keyframes aos bones selecionados anteriormente e passados como parametro
24   -def keyframe_insert(current_frame = 0, pose_bones = bpy.context.object.pose.bones, keyframe_types = ['location', 'rotation_quaternion']):
25   - # verifica se existe apenas um bone
26   - if (isinstance(pose_bones, int) or isinstance(pose_bones, str)):
27   - # verifica se existe apenas um tipo de insercao de keyframe
28   - if (isinstance(keyframe_types, str)):
29   - 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)
30   - # verifica se existe mais de um tipo de insercao de keyframe
31   - elif (isinstance(keyframe_types, list)):
32   - for keyframe_type in keyframe_types:
33   - 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)
34   - # verifica se existe mais de um bone
35   - elif (isinstance(pose_bones, list)):
36   - for bone in pose_bones:
37   - # verifica se existe apenas um tipo de insercao de keyframe
38   - if (isinstance(keyframe_types, str)):
39   - 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)
40   - # verifica se existe mais de um tipo de insercao de keyframe
41   - elif (isinstance(keyframe_types, list)):
42   - for keyframe_type in keyframe_types:
43   - 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)
44   - return
45   -
46   -# aplica biblioteca(s) de pose(s) e seu respectivo indice
47   -def apply_pose(index = 0, pose_library = list(bpy.data.actions)):
48   - # verifica se deve aplicar apenas uma biblioteca
49   - if (isinstance(pose_library, int) or isinstance(pose_library, str)):
50   - # verifica biblioteca fake_user
51   - if (bpy.data.actions[pose_library].use_fake_user):
52   - bpy.context.object.pose_library = bpy.data.actions[pose_library]
53   - bpy.ops.poselib.apply_pose(pose_index = index)
54   - # verifica se deve aplicar mais de uma biblioteca
55   - elif (isinstance(pose_library, list)):
56   - for library in pose_library:
57   - # verifica biblioteca fake_user
58   - if (library.use_fake_user):
59   - bpy.context.object.pose_library = library
60   - bpy.ops.poselib.apply_pose(pose_index = index)
61   - bpy.context.object.pose_library = None
62   - return
63   -
64   -# consolida o movimento (faz insercao dos keyframes) e incrementa a timeline
65   -def set_expression(timeline_facial, index, frame_duration = dict_duration['normal'], frame_transition = dict_transition['inicial']):
66   - library_name = util.facial_expression_id
67   - bones_facial = util.dict_bones[library_name]
68   - util.select_bones(bones_facial)
69   - # TODO separar bones 'location' e 'rotation_quaternion'
70   - keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
71   - apply_pose(index, library_name)
72   - timeline_facial += frame_transition
73   - keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
74   - timeline_facial += frame_duration
75   - keyframe_insert(timeline_facial, bones_facial, ['location', 'rotation_quaternion'])
76   - timeline_facial += frame_transition
77   - util.deselect_bones(bones_facial)
78   - return timeline_facial
79   -
80   -# decodifica objeto JSON
81   -def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_duration['normal']):
82   - global dict_duration
83   - global dict_transition
84   - index = js_facial['expressao']
85   - frame_duration = dict_duration[js_facial['duracao']]
86   - frame_transition = dict_transition[js_facial['transicao']]
87   - # insere o primeiro keyframe
88   - if (timeline_facial == 0):
89   - timeline_facial = set_expression(timeline_facial, 0, initial_interpolation)
90   - timeline_facial = set_expression(timeline_facial, index, frame_duration, frame_transition)
91   - timeline_facial = set_expression(timeline_facial, 0, frame_duration)
92   - return timeline_facial
93   -
94   -"""
95   -# unit test
96   -def main():
97   - timeline_facial = 0
98   - util.delete_all_keyframes()
99   - expressoes = list(range(0, round(bpy.data.actions[util.facial_expression_id].frame_range[1]) + 1))
100   - expressoes = [10, 11]
101   - for i in expressoes:
102   - js_facial = {
103   - "expressao": i,
104   - "transicao": "normal",
105   - "duracao": "normal"
106   - }
107   - timeline_facial = decode_expression(timeline_facial, js_facial, dict_duration['inicial'])
108   - bpy.context.scene.frame_end = timeline_facial + dict_duration['final']
109   - bpy.ops.screen.animation_play(reverse = False)
110   -
111   -if __name__ == "__main__":
112   - main()
113   -"""
114 0 \ No newline at end of file
libras.py
... ... @@ -4,6 +4,7 @@
4 4 import bpy
5 5  
6 6 # importa modulos do Python
  7 +import io
7 8 import json
8 9 import sys
9 10 import os
... ... @@ -18,25 +19,15 @@ sys.path.insert(0, getcwd)
18 19 import util
19 20 import moves
20 21 import pyutil
21   -import facial
22 22 import decode
23 23  
24   -# intervalos de interpolacao dos keyframes
25   -dict_interpolation = {
26   - 'inicial': 20,
27   - 'lento': 15,
28   - 'normal': 10,
29   - 'rapido': 5,
30   - 'final': 20
31   -}
32   -
33   -def insert_keyframe_pose_default(current_frame = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']):
  24 +def insert_keyframe_pose_default(current_frame = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ["location", "rotation_quaternion"]):
34 25 for obj in (pose_bones):
35 26 obj.bone.select = True
36 27 for type_keyframe in types_keyframe:
37 28 util.keyframe_insert(obj, type_keyframe, current_frame, False)
38 29 obj.bone.select = False
39   - return current_frame
  30 + return
40 31  
41 32 def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions):
42 33 for action in actions:
... ... @@ -54,55 +45,55 @@ def main():
54 45  
55 46 try:
56 47 js_input = json.loads(sys.argv[6])
57   - js_movimentos = js_input['movimentos']
58   - frame_jump = dict_interpolation[js_input['interpolacao']]
  48 + js_movimentos = js_input["movimentos"]
  49 + frame_jump = util.dict_interpolation[js_input["interpolacao"]]
59 50  
60 51 endFrame = pose_default(0, frame_jump)
  52 + timeline_facial = 0
61 53 timeline_mao_esquerda = 0
62 54 timeline_mao_direita = 0
63   - timeline_facial = 0
64 55  
65   - # setar pose padrao inicial em todos os bones ('location' e 'rotation_quaternion')
66   - endFrame += pose_default(dict_interpolation['inicial'])
  56 + # setar pose padrao inicial em todos os bones ("location" e "rotation_quaternion")
  57 + endFrame += pose_default(util.dict_interpolation["inicial"])
67 58  
68 59 for i in range(0, len(js_movimentos)):
  60 + timeline_facial = endFrame
69 61 timeline_mao_esquerda = endFrame
70 62 timeline_mao_direita = endFrame
71 63  
72 64 # tenta decodificar objetos JSON
73 65 try:
74   - js_facial = js_movimentos[i]['facial']
  66 + js_facial = js_movimentos[i]["facial"]
75 67 except:
76 68 js_facial = {}
77 69 try:
78   - js_mao_esquerda = js_movimentos[i]['mao_esquerda']
  70 + js_mao_esquerda = js_movimentos[i]["mao_esquerda"]
79 71 except:
80 72 js_mao_esquerda = {}
81 73 try:
82   - js_mao_direita = js_movimentos[i]['mao_direita']
  74 + js_mao_direita = js_movimentos[i]["mao_direita"]
83 75 except:
84 76 js_mao_direita = {}
85 77  
86 78 # faz tratamento dos objetos
87 79 if (js_facial == {}):
88   - print("movimento [%d] Exp facial = <Vazio>" % (i))
89   - timeline_facial = facial.set_expression(timeline_facial, 0)
  80 + pyutil.log("movimento [%d] Exp facial = <Vazio>" % (i))
90 81 else:
91   - print("movimento [%d] Exp facial = [%d]" % (i, js_facial["expressao"]))
92   - timeline_facial = facial.decode_expression(timeline_facial, js_facial)
  82 + pyutil.log("movimento [%d] Exp facial = [%d]" % (i, js_facial["expressao"]))
  83 + timeline_facial = decode.facial(js_facial, timeline_facial, frame_jump)
93 84  
94 85 if (js_mao_esquerda == {}):
95   - print("movimento [%d] Mao Esquerda = <Vazio>" % (i))
  86 + pyutil.log("movimento [%d] Mao Esquerda = <Vazio>" % (i))
96 87 # TODO posicionar mao esquerda na lateral do corpo
97 88 else:
98   - print("movimento [%d] Mao Esquerda = [%s]" % (i, next(iter(js_mao_esquerda.keys()))))
  89 + pyutil.log("movimento [%d] Mao Esquerda = [%s]" % (i, next(iter(js_mao_esquerda.keys()))))
99 90 timeline_mao_esquerda = decode.hand_mov(timeline_mao_esquerda, frame_jump, js_mao_esquerda, False)
100 91  
101 92 if (js_mao_direita == {}):
102   - print("movimento [%d] Mao Direita = <Vazio>" % (i))
  93 + pyutil.log("movimento [%d] Mao Direita = <Vazio>" % (i))
103 94 # TODO posicionar mao direita na lateral do corpo
104 95 else:
105   - print("movimento [%d] Mao Direita = [%s]" % (i, next(iter(js_mao_direita.keys()))))
  96 + pyutil.log("movimento [%d] Mao Direita = [%s]" % (i, next(iter(js_mao_direita.keys()))))
106 97 timeline_mao_direita = decode.hand_mov(timeline_mao_direita, frame_jump, js_mao_direita, True)
107 98  
108 99 endFrame = max(timeline_facial, timeline_mao_esquerda, timeline_mao_direita)
... ... @@ -110,12 +101,23 @@ def main():
110 101  
111 102 # setar pose padrao final em todos os bones (location e rotation)
112 103 endFrame = pose_default(endFrame, frame_jump)
113   - endFrame += dict_interpolation['final']
  104 + endFrame += util.dict_interpolation["final"]
  105 +
  106 + sinal = str(js_input["sinal"])
  107 + user_id = str(js_input["userId"])
  108 + directory = os.path.join(getcwd, "users", user_id)
  109 +
  110 + # exporta .blend
  111 + util.export_blend(directory, sinal + ".blend", 0, 0, endFrame)
  112 +
  113 + # exporta .json
  114 + util.export_json(js_input, directory, sinal + ".json")
114 115  
115   - util.render_sign(js_input["userId"], js_input["sinal"], endFrame)
  116 + # exporta .mp4
  117 + util.render_sign(user_id, sinal, endFrame)
116 118  
117 119 except:
118   - pyutil.print_stack_trace(__file__)
  120 + pyutil.print_stack_trace()
119 121 raise
120 122  
121 123 if __name__ == "__main__":
... ...
moves.py
... ... @@ -5,6 +5,51 @@ import math
5 5 import util
6 6 import pyutil
7 7  
  8 +def facial_insert_keyframe(current_frame):
  9 + bones_facial = util.dict_bones[util.facial_expression_id]
  10 + util.select_bones(bones_facial)
  11 + for bone in bones_facial:
  12 + for keyframe_type in ["location", "rotation_quaternion"]:
  13 + 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)
  14 + util.deselect_bones(bones_facial)
  15 +
  16 +def facial_set_expression(timeline_facial, index, frame_duration, frame_transition):
  17 + facial_insert_keyframe(timeline_facial)
  18 + util.deselect_bones()
  19 + bpy.context.object.pose_library = bpy.data.actions[util.facial_expression_id]
  20 + bpy.ops.poselib.apply_pose(pose_index = index)
  21 + bpy.context.object.pose_library = None
  22 + timeline_facial += frame_transition
  23 + facial_insert_keyframe(timeline_facial)
  24 + timeline_facial += frame_duration
  25 + facial_insert_keyframe(timeline_facial)
  26 + timeline_facial += frame_transition
  27 + return timeline_facial
  28 +
  29 +def facial(js_facial, current_frame, frame_jump):
  30 + dict_duration = {
  31 + "inicial": 5,
  32 + "lento": 15,
  33 + "normal": 10,
  34 + "rapido": 5,
  35 + "final": 5,
  36 + }
  37 + dict_transition = {
  38 + "inicial": 0,
  39 + "lento": 15,
  40 + "normal": 10,
  41 + "rapido": 5,
  42 + "final": 0
  43 + }
  44 + index = js_facial["expressao"]
  45 + frame_duration = dict_duration[js_facial["duracao"]]
  46 + frame_transition = dict_transition[js_facial["transicao"]]
  47 + if (current_frame == 0):
  48 + current_frame = facial_set_expression(current_frame, 0, initial_interpolation, dict_transition["normal"])
  49 + current_frame = facial_set_expression(current_frame, index, frame_duration, frame_transition)
  50 + current_frame = facial_set_expression(current_frame, 0, frame_duration, dict_transition["normal"])
  51 + return current_frame
  52 +
8 53 def read_hand_param(mov_param):
9 54 conf_param = mov_param['configuracao'] if 'configuracao' in mov_param else 0
10 55 artic_param = mov_param['articulacao'] if 'articulacao' in mov_param else 0
... ... @@ -26,13 +71,11 @@ def riscar(action, mov_param, bones, is_right_hand, initialFrame = 25, frameJump
26 71 currentFrame = initialFrame
27 72 handParam = read_hand_param(mov_param)
28 73 lado = "R" if is_right_hand else "L"
29   -
30 74 bnAntBraco = bpy.context.object.pose.bones["BnAntBraco." + lado]
31 75 currentFrame += frameJump
32 76 util.apply_rotation(bnAntBraco, "Z", currentFrame, bnAntBracoDegree)
33 77 currentFrame += frameJump
34 78 util.apply_rotation(bnAntBraco, "Z", currentFrame, (-1)*(bnAntBracoDegree+1))
35   -
36 79 currentFrame = initialFrame
37 80 util.setPose(action, handParam, [currentFrame], bones)
38 81 bnMao = bpy.context.object.pose.bones["BnMao." + lado]
... ... @@ -51,7 +94,6 @@ def tocar(action, mov_param, bones, is_right_hand, initialFrame = 25, degree = 3
51 94 handParam = read_hand_param(mov_param)
52 95 util.setPose(action, handParam, [initialFrame], bones)
53 96 pose = util.armature.pose.bones["ik_FK.R" if is_right_hand else "ik_FK.L"]
54   -
55 97 lado = "BnMao.R" if is_right_hand else "BnMao.L"
56 98 bnMao = bpy.context.object.pose.bones[lado]
57 99 currentFrame += frameJump
... ... @@ -66,7 +108,6 @@ def cocar(action, mov_param, bones, initialFrame = 18, frameJump = 10):
66 108 currentFrame = initialFrame
67 109 pa_index = mov_param['articulacao'] if 'articulacao' in mov_param else 0
68 110 repetition = mov_param['repeticoes'] if 'repeticoes' in mov_param else 2
69   -
70 111 for i in range(0, repetition):
71 112 util.setPose(action, [util.cocar_mao_aberta_index, pa_index, util.cocar_orientation_index], [currentFrame], bones, False)
72 113 currentFrame += frameJump
... ... @@ -81,7 +122,6 @@ def alisar(action, mov_param, bones, is_right_hand, initialFrame = 18, frameJump
81 122 handParam = read_hand_param(mov_param)
82 123 util.setPose(action, handParam, [currentFrame], bones)
83 124 boneIK = util.armature.pose.bones["ik_FK.R" if is_right_hand else "ik_FK.L"]
84   -
85 125 if (plane == "perpendicular"):
86 126 currentFrame = alisar_xy(boneIK, 1, repetition, currentFrame, frameJump, width)
87 127 elif (plane == "paralelo"):
... ... @@ -138,70 +178,192 @@ def alisar_diagonal(boneIK, to_right, repetition, initialFrame = 18, frameJump =
138 178 # raio: "grande" raio = 1.5, velocidade: "rapido" periodo = 45
139 179 # raio: "grande" raio = 1.5, velocidade: "normal" periodo = 55
140 180 # raio: "grande" raio = 1.5, velocidade: "lento" periodo = 65
141   -# @param obj: (objeto) bone, mesh, e.g.
142   -# @param current_frame: (int) posicao onde o primeiro keyframe vai ser inserido
143   -# @param raio: (int) raio da circunferencia
144   -# @param periodo: (int) quantidade de keyframes necessarios para completar uma volta completa
145   -# @param x: (int) in [0,1,2] define qual eixo vai variar no seno (0 = eixo X, 1 = eixo Y, 2 = eixo Z)
146   -# @param y: (int) in [0,1,2] define qual eixo vai variar no cosseno (0 = eixo X, 1 = eixo Y, 2 = eixo Z)
147   -# @param usar_lado_oposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar)
148   -# @param usar_sentido_oposto (bool) inverte o sentido do movimento (horario para anti-horario)
149   -def circular(obj, current_frame, raio, periodo, x = 0, y = 1, usar_lado_oposto = False, usar_sentido_oposto = False, meia_volta = False):
150   - # limita inferiormente
151   - if (periodo < 16):
152   - periodo = 16
153   - # limita superiormente
154   - elif (periodo > 360):
155   - periodo = 360
156   - # muda lado inicial
157   - if (usar_lado_oposto):
158   - k = round(periodo / 2)
  181 +def circular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular = False):
  182 + dict_ray = {
  183 + "pequeno": 0.5,
  184 + "normal": 1.0,
  185 + "grande": 1.5
  186 + }
  187 + dict_period = {
  188 + "lento": 55,
  189 + "normal": 45,
  190 + "rapido": 35
  191 + }
  192 + ray = dict_ray[js_movement["raio"]]
  193 + period = dict_period[js_movement["velocidade"]]
  194 + opposite_side = js_movement["lado_oposto"]
  195 + reverse_way = js_movement["sentido_inverso"]
  196 + actions = util.right_hand_actions if (is_right_hand) else util.left_hand_actions
  197 + hand_param = read_hand_param(js_movement)
  198 + bones = util.right_bones_conf if (is_right_hand) else util.left_bones_conf
  199 + ik = bpy.context.object.pose.bones["ik_FK.R" if (is_right_hand) else "ik_FK.L"]
  200 + if (js_movement["velocidade"] == "lento"):
  201 + period += 10
  202 + elif (js_movement["velocidade"] == "rapido"):
  203 + period -= 10
  204 + if (js_movement["plano"] == "frente-esquerda"):
  205 + x, y = 2, 0
  206 + elif (js_movement["plano"] == "frente-cima"):
  207 + x, y = 2, 1
  208 + else:
  209 + x, y = 0, 1
  210 + k = round(period / 2) if (opposite_side) else 0
  211 + x %= 3
  212 + y %= 3
  213 + if (reverse_way):
  214 + tmp = x
  215 + x = y
  216 + y = tmp
  217 + util.setPose(actions, hand_param, [current_frame], bones, False)
  218 + util.keyframe_insert(bones, "location", current_frame, False, False)
  219 + ik_loc = [ik.location[0], ik.location[1], ik.location[2]]
  220 + limit = period + k - 1
  221 + if (is_semicircular):
  222 + limit = round(period / 2) + k
  223 + for i in range(k, limit + 1):
  224 + bpy.context.object.pose_library = bpy.data.actions[util.conf_direita_id if (is_right_hand) else util.conf_esquerda_id]
  225 + bpy.ops.poselib.apply_pose(pose_index = hand_param[0])
  226 + bpy.context.object.pose_library = None
  227 + util.keyframe_insert(bones, "location", current_frame, False)
  228 + util.keyframe_insert(bones, "rotation_quaternion", current_frame, False)
  229 + ik.location[x] = ik_loc[x] + (ray * math.cos(i / period * (2 * math.pi)))
  230 + ik.location[y] = ik_loc[y] + (ray * math.sin(i / period * (2 * math.pi)))
  231 + util.keyframe_insert(ik, "location", current_frame)
  232 + util.keyframe_insert(ik, "rotation_quaternion", current_frame, False)
  233 + current_frame += 1
  234 + return current_frame
  235 +
  236 +def helicoidal(js_movement, current_frame, frame_jump, is_right_hand):
  237 + dict_ray = {
  238 + "pequeno": 0.5,
  239 + "normal": 1.0,
  240 + "grande": 1.5
  241 + }
  242 + dict_period = {
  243 + "lento": 55,
  244 + "normal": 45,
  245 + "rapido": 35
  246 + }
  247 + ray = dict_ray[js_movement["raio"]]
  248 + period = dict_period[js_movement["velocidade"]]
  249 + opposite_side = js_movement["lado_oposto"]
  250 + reverse_way = js_movement["sentido_inverso"]
  251 + actions = util.right_hand_actions if (is_right_hand) else util.left_hand_actions
  252 + hand_param = read_hand_param(js_movement)
  253 + bones = util.right_bones_conf if (is_right_hand) else util.left_bones_conf
  254 + ik = bpy.context.object.pose.bones["ik_FK.R" if (is_right_hand) else "ik_FK.L"]
  255 + if (js_movement["velocidade"] == "lento"):
  256 + period += 10
  257 + elif (js_movement["velocidade"] == "rapido"):
  258 + period -= 10
  259 + if (js_movement["plano"] == "frente-esquerda"):
  260 + x, y, z = 2, 0, 1
  261 + elif (js_movement["plano"] == "frente-cima"):
  262 + x, y, z = 2, 1, 0
159 263 else:
160   - k = 0
161   - # evita estouro dos indices
  264 + x, y, z = 0, 1, 2
  265 + k = round(period / 2) if (opposite_side) else 0
162 266 x %= 3
163 267 y %= 3
164   - # inverte direcao do movimento
165   - if (usar_sentido_oposto):
  268 + if (reverse_way):
166 269 tmp = x
167 270 x = y
168 271 y = tmp
169   - # copia posicao inicial para transladar
170   - loc = [obj.location[0], obj.location[1], obj.location[2]]
171   - # semi-circular
172   - limite = periodo + k
173   - if (meia_volta):
174   - limite = round(limite / 2)
175   - for i in range(k, limite + 1):
176   - # reduz a quantidade de keyframes
177   - if (current_frame % 2 == 0):
178   - obj.location[x] = loc[x] + (raio * math.cos(i / periodo * (2 * math.pi)))
179   - obj.location[y] = loc[y] + (raio * math.sin(i / periodo * (2 * math.pi)))
180   - util.keyframe_insert(obj, 'location', current_frame)
  272 + util.setPose(actions, hand_param, [current_frame], bones, False)
  273 + util.keyframe_insert(bones, "location", current_frame, False, False)
  274 + ik_loc = [ik.location[0], ik.location[1], ik.location[2]]
  275 + limit = period + k - 1
  276 + for i in range(k, 2 * (limit + 1)):
  277 + bpy.context.object.pose_library = bpy.data.actions[util.conf_direita_id if (is_right_hand) else util.conf_esquerda_id]
  278 + bpy.ops.poselib.apply_pose(pose_index = hand_param[0])
  279 + bpy.context.object.pose_library = None
  280 + util.keyframe_insert(bones, "location", current_frame, False)
  281 + util.keyframe_insert(bones, "rotation_quaternion", current_frame, False)
  282 + ik.location[x] = ik_loc[x] + (ray * math.cos(i / period * (2 * math.pi)))
  283 + ik.location[y] = ik_loc[y] + (ray * math.sin(i / period * (2 * math.pi)))
  284 + ik.location[z] = ik_loc[z] + (i / period) - ray
  285 + util.keyframe_insert(ik, "location", current_frame)
  286 + util.keyframe_insert(ik, "rotation_quaternion", current_frame, False)
181 287 current_frame += 1
182   - util.keyframe_insert(obj, 'location', current_frame)
183   - return periodo - 1
  288 + return current_frame
184 289  
185 290 def pontual(js_movement, current_frame, frame_jump, is_right_hand):
186 291 hand_param = read_hand_param(js_movement)
187 292 bones = util.right_bones_conf if is_right_hand else util.left_bones_conf
188 293 hand_actions = util.right_hand_actions if is_right_hand else util.left_hand_actions
189   - util.keyframe_insert(bones, 'location', current_frame)
  294 + util.keyframe_insert(bones, "location", current_frame)
190 295 current_frame += frame_jump
191 296 util.setPose(hand_actions, hand_param, [current_frame], bones)
192 297 current_frame += frame_jump
193   - util.keyframe_insert(bones, 'location', current_frame)
  298 + util.keyframe_insert(bones, "location", current_frame)
194 299 return current_frame
195 300  
196 301 def retilineo(js_movement, current_frame, frame_jump, is_right_hand):
197   - hand_param = [js_movement['configuracao'], js_movement['articulacao_inicial'], js_movement['orientacao']]
  302 + hand_param = [js_movement["configuracao_inicial"], js_movement["articulacao_inicial"], js_movement["orientacao_inicial"]]
198 303 bones = util.right_bones_conf if is_right_hand else util.left_bones_conf
199 304 hand_actions = util.right_hand_actions if is_right_hand else util.left_hand_actions
200   - util.keyframe_insert(bones, 'location', current_frame)
  305 + util.keyframe_insert(bones, "location", current_frame)
201 306 current_frame += frame_jump
202 307 util.setPose(hand_actions, hand_param, [current_frame], bones)
203   - current_frame += 2* frame_jump
204   - hand_param = [js_movement['configuracao'], js_movement['articulacao_final'], js_movement['orientacao']]
  308 + current_frame += 2 * frame_jump
  309 + hand_param = [js_movement["configuracao_final"], js_movement["articulacao_final"], js_movement["orientacao_final"]]
205 310 util.setPose(hand_actions, hand_param, [current_frame], bones)
206   - util.keyframe_insert(bones, 'location', current_frame)
  311 + util.keyframe_insert(bones, "location", current_frame)
  312 + return current_frame
  313 +
  314 +def semicircular(js_movement, current_frame, frame_jump, is_right_hand):
  315 + return circular(js_movement, current_frame, frame_jump, is_right_hand, True)
  316 +
  317 +def senoidal(js_movement, current_frame, frame_jump, is_right_hand):
  318 + dict_ray = {
  319 + "pequeno": 0.5,
  320 + "normal": 1.0,
  321 + "grande": 1.5
  322 + }
  323 + dict_period = {
  324 + "lento": 55,
  325 + "normal": 45,
  326 + "rapido": 35
  327 + }
  328 + ray = dict_ray[js_movement["raio"]]
  329 + period = dict_period[js_movement["velocidade"]]
  330 + opposite_side = js_movement["lado_oposto"]
  331 + reverse_way = js_movement["sentido_inverso"]
  332 + actions = util.right_hand_actions if (is_right_hand) else util.left_hand_actions
  333 + hand_param = read_hand_param(js_movement)
  334 + bones = util.right_bones_conf if (is_right_hand) else util.left_bones_conf
  335 + ik = bpy.context.object.pose.bones["ik_FK.R" if (is_right_hand) else "ik_FK.L"]
  336 + if (js_movement["velocidade"] == "lento"):
  337 + period += 10
  338 + elif (js_movement["velocidade"] == "rapido"):
  339 + period -= 10
  340 + if (js_movement["plano"] == "frente-esquerda"):
  341 + x, y, z = 2, 0, 1
  342 + elif (js_movement["plano"] == "frente-cima"):
  343 + x, y, z = 2, 1, 0
  344 + else:
  345 + x, y, z = 0, 1, 2
  346 + k = round(period / 2) if (opposite_side) else 0
  347 + x %= 3
  348 + y %= 3
  349 + if (reverse_way):
  350 + tmp = x
  351 + x = y
  352 + y = tmp
  353 + util.setPose(actions, hand_param, [current_frame], bones, False)
  354 + util.keyframe_insert(bones, "location", current_frame, False, False)
  355 + ik_loc = [ik.location[0], ik.location[1], ik.location[2]]
  356 + limit = period + k - 1
  357 + for i in range(k, 2 * (limit + 1)):
  358 + bpy.context.object.pose_library = bpy.data.actions[util.conf_direita_id if (is_right_hand) else util.conf_esquerda_id]
  359 + bpy.ops.poselib.apply_pose(pose_index = hand_param[0])
  360 + bpy.context.object.pose_library = None
  361 + util.keyframe_insert(bones, "location", current_frame, False)
  362 + util.keyframe_insert(bones, "rotation_quaternion", current_frame, False)
  363 + ik.location[x] = ik_loc[x] + (ray * math.cos(i / period * (2 * math.pi)))
  364 + ik.location[y] = ik_loc[y] + (ray )#* math.sin(i / period * (2 * math.pi)))
  365 + #ik.location[z] = ik_loc[z] + (i / period) - ray
  366 + util.keyframe_insert(ik, "location", current_frame)
  367 + util.keyframe_insert(ik, "rotation_quaternion", current_frame, False)
  368 + current_frame += 1
207 369 return current_frame
208 370 \ No newline at end of file
... ...
pyutil.py
1 1 # -*- coding: UTF-8 -*-
2 2  
3   -# @def Função para obter data e hora atual do sistema
4   -# @param string Formato de data e hora
5   -# @return string Retorna data e hora do sistema no momento da chamada
6   -def getTimeStamp(dtFrmt='%Y-%m-%d_%H.%M.%S.%f'):
7   - from datetime import datetime
8   - if (dtFrmt == '%Y-%m-%d_%H.%M.%S.%f'):
9   - # [:-3] Remove 3 casas decimais dos milisegundos (ms)
10   - return datetime.now().strftime(dtFrmt)[:-3]
  3 +import datetime
  4 +import logging
  5 +import os
  6 +import shutil
  7 +import sys
  8 +
  9 +# @def funcao para obter data e hora atual do sistema
  10 +# @param string formato de data e hora
  11 +# @return string retorna data e hora do sistema no momento da chamada
  12 +def getTimeStamp(date_fmt = "%Y-%m-%d %H:%M:%S.%f"):
  13 + if ("%f" in date_fmt):
  14 + # [:-3] remove 3 casas decimais dos milisegundos (ms)
  15 + return datetime.datetime.now().strftime(date_fmt)[:-3]
11 16 else:
12   - return datetime.now().strftime(dtFrmt)
13   -
14   -# @def Função para gravar log dos eventos em arquivo
15   -# @param string Mensagem a ser salva
16   -# @param int indice do tipo de log 1: Debug, 2: Info, 3: Warn, 4: Error, 5: Critical
17   -# @param String Caminho completo do arquivo de logs
18   -# @param String Formato de tempo utilizado
19   -def log(logMsg="", logLevel=2, logFile="events.log", dtFrmt='%Y-%m-%d %H:%M:%S'):
20   - import logging
21   -
22   - logLevelArray = ["", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" ]
23   - logLevel %= len(logLevelArray)
24   - print("[%s] log %s: %s" % (getTimeStamp(), logLevelArray[logLevel], logMsg))
25   -
26   - #logFormat='[%(asctime)s.%(msecs).03d] %(levelname)s: <User: %(name)s> <Module: %(module)s> <Function: %(funcName)s>: %(message)s'
27   - logFormat='[%(asctime)s.%(msecs).03d] %(levelname)s: %(message)s'
28   -
29   - if (logLevel == 1):
30   - logging.basicConfig(filename=logFile, datefmt=dtFrmt, format=logFormat, level=logging.DEBUG)
31   - logging.Formatter(fmt='%(asctime)s',datefmt='%Y/%m/%d,%H:%M:%S.%f')
32   - logging.debug(logMsg)
33   -
34   - elif (logLevel == 2):
35   - logging.basicConfig(filename=logFile, datefmt=dtFrmt, format=logFormat, level=logging.INFO)
36   - logging.Formatter(fmt='%(asctime)s',datefmt='%Y/%m/%d,%H:%M:%S.%f')
37   - logging.info(logMsg)
38   -
39   - elif (logLevel == 3):
40   - logging.basicConfig(filename=logFile, datefmt=dtFrmt, format=logFormat, level=logging.WARN)
41   - logging.Formatter(fmt='%(asctime)s',datefmt='%Y/%m/%d,%H:%M:%S.%f')
42   - logging.warn(logMsg)
43   -
44   - elif (logLevel == 4):
45   - logging.basicConfig(filename=logFile, datefmt=dtFrmt, format=logFormat, level=logging.ERROR)
46   - logging.Formatter(fmt='%(asctime)s',datefmt='%Y/%m/%d,%H:%M:%S.%f')
47   - logging.error(logMsg)
48   -
49   - elif (logLevel == 5):
50   - logging.basicConfig(filename=logFile, datefmt=dtFrmt, format=logFormat, level=logging.CRITICAL)
51   - logging.Formatter(fmt='%(asctime)s',datefmt='%Y/%m/%d,%H:%M:%S.%f')
52   - logging.critical(logMsg)
53   -
54   -def test_log():
55   - msg = " This is a message "
56   - log(msg + "Debug", 1)
57   - log(msg + "Info", 2)
58   - log(msg + "Warn", 3)
59   - log(msg + "Error", 4)
60   - log(msg + "Critical", 5)
61   -
62   -# test_log()
63   -
64   -# @def Função para exibir exceção
65   -# @param string deve ser passado: "__file__" para identificar em qual arquivo ocorreu a exceção
66   -# @return int Retorna 1
67   -def print_stack_trace(fromFile):
68   - from sys import exc_info
69   - from os.path import basename
  17 + return datetime.datetime.now().strftime(date_fmt)
  18 +
  19 +# @def funcao para gravar log dos eventos em arquivo
  20 +# @param string mensagem a ser salva
  21 +# @param int indice do tipo de log 0: apenas print, 1: debug, 2: info, 3: warn, 4: error, 5: critical
  22 +# @param string caminho completo do arquivo de logs
  23 +# @param string formato de tempo utilizado
  24 +# @return none
  25 +def log(msg = "", log_level = 2, log_file = "events.log"):
  26 + dict_level = {
  27 + 0: ["Print", None, None],
  28 + 1: ["DEBUG", logging.DEBUG, logging.debug],
  29 + 2: ["INFO", logging.INFO, logging.info],
  30 + 3: ["WARNING", logging.WARN, logging.warn],
  31 + 4: ["ERROR", logging.ERROR, logging.error],
  32 + 5: ["CRITICAL", logging.CRITICAL, logging.critical]
  33 + }
  34 + # log_format = "[%(asctime)s.%(msecs).03d] %(levelname)s: <User: %(name)s> <Module: %(module)s> <Function: %(funcName)s>: %(message)s"
  35 + log_format = "[%(asctime)s.%(msecs).03d] %(levelname)s: %(message)s"
  36 + date_fmt = "%Y-%m-%d %H:%M:%S"
  37 + logging.basicConfig(filename = log_file, datefmt = date_fmt, format = log_format, level = dict_level[log_level][1])
  38 + logging.Formatter(fmt = "%(asctime)s", datefmt = date_fmt)
  39 + log_level %= len(dict_level)
  40 + write_mode = dict_level[log_level][2]
  41 + print("[%s] %s: %s" % (getTimeStamp(), dict_level[log_level][0], msg))
  42 + if (write_mode != None):
  43 + write_mode(msg)
  44 + return
  45 +
  46 +# @def funcao para exibir excecao
  47 +# @param string deve ser passado: "__file__" para identificar em qual modulo ocorreu a excecao
  48 +# @return int retorna 1
  49 +def print_stack_trace():
70 50 error = "\n File name: %s\n Function name: %s\n Line code: %s\n Type exception: %s\n Message: %s" % (
71   - basename(fromFile), # basename(exc_info()[2].tb_frame.f_code.co_filename),
72   - exc_info()[2].tb_frame.f_code.co_name,
73   - exc_info()[2].tb_lineno,
74   - exc_info()[0].__name__,
75   - exc_info()[1]
  51 + os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename),
  52 + sys.exc_info()[2].tb_frame.f_code.co_name,
  53 + sys.exc_info()[2].tb_lineno,
  54 + sys.exc_info()[0].__name__,
  55 + sys.exc_info()[1]
76 56 )
77 57 log(error, 4)
78 58 return 1
79 59  
80   -# @def Função que verifica se um arquivo existe
81   -# @param string filePath: Caminho do arquivo a ser checado
82   -# @return bool Verdadeiro se o arquivo existir, Falso caso contrário
83   -def file_exists(filePath):
84   - from os.path import isfile, exists
85   - if ((isfile(filePath) == 1) and (exists(filePath) == 1)):
  60 +# @def funcao que verifica se um arquivo existe
  61 +# @param string caminho do arquivo a ser checado
  62 +# @return bool verdadeiro se o arquivo existir, falso caso contrario
  63 +def file_exists(file_path):
  64 + if ((os.path.isfile(file_path) == 1) and (os.path.exists(file_path) == 1)):
86 65 return True
87 66 else:
88 67 return False
89 68  
90   -# @def Função para renomear arquivo de video gerado pelo blender
91   -# @see entrada: /temp/arquivo_video_0001-0250.mp4
92   -# @see saida: /temp/arquivo_video.mp4
93   -# @param string fileFullPath: Caminho do arquivo a ser renomeado
94   -# @param bool useTimeStamp: Renomeia o arquivo de acordo com a data e hora do sistema
95   -# @param bool overwrite: Sobreescreve o arquivo
96   -# @return string Retorna o nome do arquivo renomeado
97   -def file_rename(fileFullPath, useTimeStamp = False, overwrite = True):
98   - from shutil import move
99   - from os.path import abspath, basename, dirname, join, splitext
100   - if (file_exists(fileFullPath) == False):
  69 +# @def funcao para renomear arquivo de video gerado pelo blender
  70 +# entrada: /temp/arquivo_video_0001-0250.mp4
  71 +# saida: /temp/arquivo_video.mp4
  72 +# @param string caminho do arquivo a ser renomeado
  73 +# @param bool renomeia o arquivo de acordo com a data e hora do sistema
  74 +# @param bool sobreescreve o arquivo
  75 +# @return string retorna o nome do arquivo renomeado
  76 +def file_rename(file_full_path, use_time_stamp = False, overwrite = True):
  77 + if (file_exists(file_full_path) == False):
101 78 return ""
102   - filePath = dirname(abspath(fileFullPath))
103   - filename = basename(splitext(fileFullPath)[0])
104   - extension = splitext(fileFullPath)[1]
105   - filenameInv = ""
106   - isValidChar = False
107   -
108   - # Percorre o "filename" do final para o inicio copiando caracteres após o primeiro '_' encontrado
  79 + file_path = os.path.dirname(os.path.abspath(file_full_path))
  80 + filename = os.path.basename(os.path.splitext(file_full_path)[0])
  81 + extension = os.path.splitext(file_full_path)[1]
  82 + filename_reversed = ""
  83 + valid_char = False
  84 + # percorre o "filename" do final para o inicio copiando caracteres apos o primeiro "_" encontrado
109 85 for char in reversed(filename):
110   - if (isValidChar == True):
111   - filenameInv += char
112   - if (char == '_'):
113   - isValidChar = True
  86 + if (valid_char == True):
  87 + filename_reversed += char
  88 + if (char == "_"):
  89 + valid_char = True
114 90 try:
115   -
116   - # Inverte sequencia de caracteres que foi copiada
117   - filenameInv = filenameInv[::-1]
118   -
119   - if (useTimeStamp == True):
120   - # Recupera novo fullPath + nome do arquivo + data/hora + extensão
121   - newFilename = join(filePath, "%s_%s%s" % (filenameInv, getTimeStamp(), extension))
  91 + # inverte sequencia de caracteres que foi copiada
  92 + filename_reversed = filename_reversed[::-1]
  93 + if (use_time_stamp == True):
  94 + # recupera novo file_full_path + nome do arquivo + data/hora + extensao
  95 + new_filename = os.path.join(file_path, "%s_%s%s" % (filename_reversed, getTimeStamp(), extension))
122 96 else:
123   - # Recupera novo fullPath + nome do arquivo + extensão
124   - newFilename = join(filePath, "%s%s" % (filenameInv, extension))
125   -
126   - # Enumera o nome do arquivo caso o parametro "overwrite" seja "False" e o arquivo já exista
  97 + # recupera novo file_full_path + nome do arquivo + extensao
  98 + new_filename = os.path.join(file_path, "%s%s" % (filename_reversed, extension))
  99 + # Enumera o nome do arquivo caso o parametro "overwrite" seja "False" e o arquivo ja exista
127 100 if (overwrite == False):
128 101 count = 0
129   - while (file_exists(newFilename) == True):
  102 + while (file_exists(new_filename) == True):
130 103 count += 1
131   - # newFilename = join(filePath, "%s_%i%s" % (filenameInv, count, extension))
132   - newFilename = join(filePath, "%s_%0.4i%s" % (filenameInv, count, extension))
133   -
134   - log("Rename: '%s' to: '%s'" %(fileFullPath, newFilename))
135   - move(fileFullPath, newFilename)
136   - return newFilename
137   -
138   - except Exception as e:
139   - printStackTrace(__file__)
  104 + # new_filename = join(file_path, "%s_%i%s" % (filename_reversed, count, extension))
  105 + new_filename = os.path.join(file_path, "%s_%0.4i%s" % (filename_reversed, count, extension))
  106 + # log('rename: "%s" to: "%s"' %(file_full_path, new_filename))
  107 + shutil.move(file_full_path, new_filename)
  108 + return new_filename
  109 + except Exception:
  110 + print_stack_trace()
140 111 return ""
  112 +
  113 +"""
  114 +# unit test
  115 +def main():
  116 + msg = "This is a message of "
  117 + log(msg + "Print", 0)
  118 + log(msg + "Debug", 1)
  119 + log(msg + "Info", 2)
  120 + log(msg + "Warn", 3)
  121 + log(msg + "Error", 4)
  122 + log(msg + "Critical", 5)
  123 + filename = "sample_001-250.mp4"
  124 + video = open(filename, "w")
  125 + video.write
  126 + video.close
  127 + file_rename(filename)
  128 + return
  129 +
  130 +if __name__ == "__main__":
  131 + main()
  132 +"""
141 133 \ No newline at end of file
... ...
util.py
1 1 # -*- coding: UTF-8 -*-
2 2  
3 3 import bpy
  4 +import copy
  5 +import json
4 6 import math
5 7 import os
6   -import sys
7   -import copy
8 8 import pyutil
  9 +import sys
9 10 from bmesh_collision import bmesh_check_intersect_objects
10 11  
11 12 armature = bpy.context.scene.objects.get('Armature.001')
... ... @@ -20,15 +21,13 @@ dict_bones = {
20 21 "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']
21 22 }
22 23  
23   -right_bones_conf = dict_bones["01_conf_direita"] + dict_bones["03_pa_direita"] + dict_bones["05_orient_direita"]
24   -
25   -left_bones_conf = dict_bones["02_conf_esquerda"] + dict_bones["04_pa_esquerda"] + dict_bones["06_orient_esquerda"]
26   -
27   -# Vetor com indices de cada bone do lado direito
28   -#rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66]
29   -
30   -# Vetor com indices de cada bone do lado esquerdo
31   -#leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82]
  24 +dict_interpolation = {
  25 + "inicial": 20,
  26 + "lento": 15,
  27 + "normal": 10,
  28 + "rapido": 5,
  29 + "final": 20
  30 +}
32 31  
33 32 # Movimento coçar - Índices de poses
34 33 cocar_mao_aberta_index = 55
... ... @@ -36,21 +35,29 @@ cocar_mao_fechada_index = 24
36 35 cocar_orientation_index = 11
37 36  
38 37 # Action expressão facial
39   -facial_expression_id = '07_facial'
  38 +facial_expression_id = "07_facial"
40 39 facial_expression_action = [facial_expression_id]
41 40  
42 41 # Actions mão direita
43   -conf_direita_id = '01_conf_direita'
44   -pa_direita_id = '03_pa_direita'
45   -orient_direita_id = '05_orient_direita'
  42 +conf_direita_id = "01_conf_direita"
  43 +pa_direita_id = "03_pa_direita"
  44 +orient_direita_id = "05_orient_direita"
46 45 right_hand_actions = [conf_direita_id, pa_direita_id, orient_direita_id]
47 46  
48 47 # Actions mão esquerda
49   -conf_esquerda_id = '02_conf_esquerda'
50   -pa_esquerda_id = '04_pa_esquerda'
51   -orient_esquerda_id = '06_orient_esquerda'
  48 +conf_esquerda_id = "02_conf_esquerda"
  49 +pa_esquerda_id = "04_pa_esquerda"
  50 +orient_esquerda_id = "06_orient_esquerda"
52 51 left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id]
53 52  
  53 +all_actions = [conf_direita_id, conf_esquerda_id, pa_direita_id, pa_esquerda_id, orient_direita_id, orient_esquerda_id, facial_expression_id]
  54 +
  55 +all_bones = dict_bones[conf_direita_id] + dict_bones[conf_esquerda_id] + dict_bones[pa_direita_id] + dict_bones[pa_esquerda_id] + dict_bones[orient_direita_id] + dict_bones[orient_esquerda_id] + dict_bones[facial_expression_id]
  56 +
  57 +right_bones_conf = dict_bones[conf_direita_id] + dict_bones[pa_direita_id] + dict_bones[orient_direita_id]
  58 +
  59 +left_bones_conf = dict_bones[conf_esquerda_id] + dict_bones[pa_esquerda_id] + dict_bones[orient_esquerda_id]
  60 +
54 61 last_keyframe_dict = {}
55 62  
56 63 def select_bones(bones = bpy.context.object.pose.bones):
... ... @@ -86,7 +93,6 @@ def delete_all_keyframes():
86 93 obj.animation_data_clear()
87 94 return
88 95  
89   -# Função responsável por selecionar as pose-libs e setar os frames
90 96 def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True):
91 97 for x in range(len(positionFrames)):
92 98 for l in range(len(actions)):
... ... @@ -110,7 +116,7 @@ def internal_keyframe_insert(bone, path, positionFrame, collisionFlag = True, ro
110 116 if ("ik_FK" in bone.name and bone.location.z < 1):
111 117 bone.location.z = 1
112 118 bone.bone.select = True
113   - bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame)
  119 + bone.keyframe_insert(data_path = path, index = -1, group = bone.name, frame = positionFrame)
114 120 bone.bone.select = False
115 121 keyframe_id = bone.name + "_" + path
116 122 last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0
... ... @@ -184,7 +190,6 @@ def check_collision(objName, otherObjName, initFrame, endFrame):
184 190 scene = bpy.context.scene
185 191 startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2))
186 192 collisionFrame = -1
187   -
188 193 for i in range(startFrame, endFrame + 1, 1):
189 194 scene.frame_set(i)
190 195 obj = scene.objects.get(objName)
... ... @@ -222,10 +227,9 @@ def configure_output():
222 227 bpy.context.scene.render.tile_y = 240
223 228 return
224 229  
225   -def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end):
  230 +def render_sign(user_id = "", sinal = "", frame_final = bpy.context.scene.frame_end):
226 231 getcwd = os.path.dirname(os.path.abspath(__file__))
227   - bpy.context.scene.render.filepath = getcwd + "/users/" + str(user_id) + "/"+ nome_sinal + "_"
228   - bpy.ops.wm.save_as_mainfile(filepath=getcwd + "/users/" + str(user_id) + "/"+ nome_sinal + ".blend")
  232 + bpy.context.scene.render.filepath = os.path.join(getcwd, "users", user_id, sinal + "_")
229 233 bpy.context.scene.frame_end = frame_final
230 234 pyutil.log("Gerando Video... Frames: %i" % (frame_final))
231 235 bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
... ... @@ -233,6 +237,39 @@ def render_sign(user_id, nome_sinal = &quot;sinal&quot;, frame_final = bpy.context.scene.f
233 237 bpy.ops.wm.quit_blender()
234 238 return
235 239  
  240 +def make_dir(directory):
  241 + if not os.path.exists(directory):
  242 + os.makedirs(directory)
  243 + return True
  244 + return False
  245 +
  246 +def export_blend(directory, filename, frame_start, frame_current, frame_end):
  247 + tmp_frame_start = bpy.context.scene.frame_start
  248 + tmp_frame_current = bpy.context.scene.frame_current
  249 + tmp_frame_end = bpy.context.scene.frame_end
  250 + bpy.context.scene.frame_start = frame_start
  251 + bpy.context.scene.frame_current = frame_current
  252 + bpy.context.scene.frame_end = frame_end
  253 + make_dir(directory)
  254 + bpy.ops.wm.save_as_mainfile(filepath = os.path.join(directory, filename))
  255 + bpy.context.scene.frame_start = tmp_frame_start
  256 + bpy.context.scene.frame_current = tmp_frame_current
  257 + bpy.context.scene.frame_end = tmp_frame_end
  258 +
  259 +def export_json(obj, directory, filename, inline = True):
  260 + make_dir(directory)
  261 + fp = open(os.path.join(directory, filename), 'w', encoding = "utf-8")
  262 + fp.write(
  263 + json.dumps(
  264 + obj,
  265 + ensure_ascii = False,
  266 + indent = None if (inline) else 4,
  267 + separators = (",", ":") if (inline) else None
  268 + )
  269 + )
  270 + fp.close
  271 + return
  272 +
236 273 def validate_rotation(bone, endFrame, startFrame = 0):
237 274 if (endFrame - startFrame == 1):
238 275 return True
... ...