Commit e313bcb0251531f63b4c31711c70355bbafcbeea
1 parent
42f9b71d
Exists in
master
Atualiza movimento Circular, Helicoidal, Facial
Showing
8 changed files
with
505 additions
and
470 deletions
Show diff stats
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 = "sinal", 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 | ... | ... |