Commit 0f2ad8a3d6600d6df5181e70ad917590e1cf4300

Authored by André Araújo
1 parent 7736a4b1
Exists in master

Corrige transição da expressão facial, realiza outros pequenos ajustes

Makefile
1   -JSON_ALL = \
2   -'{ \
3   - "userId": "lavid", \
4   - "sinal": "Modelo JSON", \
5   - "interpolacao": "lento|normal|rapido", \
6   - "movimentos": [ \
7   - { \
8   - "facial": { \
9   - "expressao": 0..21, \
10   - "transicao": "lento|normal|rapido", \
11   - "duracao": "lento|normal|rapido" \
12   - }, \
13   - "mao_esquerda": { \
14   - "circular": { \
15   - "plano": "frente-esquerda|frente-cima|esquerda-cima", \
16   - "raio": "pequeno|medio|grande", \
17   - "velocidade": "lento|normal|rapido", \
18   - "lado_oposto": true|false, \
19   - "sentido_inverso": true|false, \
20   - "articulacao": 0..124, \
21   - "configuracao": 0..60, \
22   - "orientacao": 0..142 \
23   - }, \
24   - "semicircular": { \
25   - "plano": "frente-esquerda|frente-cima|esquerda-cima", \
26   - "raio": "pequeno|medio|grande", \
27   - "lado_oposto": true|false, \
28   - "sentido_inverso": true|false, \
29   - "articulacao": 0..124, \
30   - "configuracao": 0..60, \
31   - "orientacao": 0..142 \
32   - }, \
33   - "contato": { \
34   - "alisar": { \
35   - "movimento_orientacao": "perpendicular|paralelo|diagonal-direita|diagonal-esquerda", \
36   - "articulacao": 0..124, \
37   - "configuracao": 0..60, \
38   - "orientacao": 0..142 \
39   - }, \
40   - "cocar": { \
41   - "articulacao": 0..124, \
42   - "configuracao": 0..60, \
43   - "orientacao": 0..142 \
44   - }, \
45   - "tocar": { \
46   - "articulacao": 0..124, \
47   - "configuracao": 0..60, \
48   - "orientacao": 0..142 \
49   - }, \
50   - "riscar": { \
51   - "articulacao": 0..124, \
52   - "configuracao": 0..60, \
53   - "orientacao": 0..142 \
54   - } \
55   - }, \
56   - "espiral": { \
57   - "plano": "frente-esquerda|frente-cima|esquerda-cima", \
58   - "raio": "pequeno|medio|grande", \
59   - "lado_oposto": true|false, \
60   - "sentido_inverso": true|false, \
61   - "articulacao": 0..124, \
62   - "configuracao": 0..60, \
63   - "orientacao": 0..142 \
64   - }, \
65   - "helicoidal": { \
66   - "plano": "frente-esquerda|frente-cima|esquerda-cima", \
67   - "raio": "pequeno|medio|grande", \
68   - "lado_oposto": true|false, \
69   - "sentido_inverso": true|false, \
70   - "articulacao": 0..124, \
71   - "configuracao": 0..60, \
72   - "orientacao": 0..142 \
73   - }, \
74   - "pontual": { \
75   - "articulacao": 0..124, \
76   - "configuracao": 0..60, \
77   - "orientacao": 0..142 \
78   - }, \
79   - "retilineo": { \
80   - "velocidade": "lento|normal|rapido", \
81   - "articulacao_inicial": 0..124, \
82   - "articulacao_final": 0..124, \
83   - "configuracao": 0..60, \
84   - "orientacao": 0..142 \
85   - }, \
86   - "senoidal": { \
87   - "direcao": "frente|esquerda|cima", \
88   - "direcao_oposta": true|false, \
89   - "eixo_fixo": "frente-tras|esquerda-direita|cima-baixo", \
90   - "comprimento_onda": "pequeno|medio|grande", \
91   - "articulacao": 0..124, \
92   - "configuracao": 0..60, \
93   - "orientacao": 0..142 \
94   - } \
95   - }, \
96   - "mao_direita": { \
97   - } \
98   - } \
99   - ] \
100   -}'
101   -
102 1 JSON = \
103 2 '{ \
104 3 "userId": "lavid", \
105   - "sinal": "Modelo JSON 2", \
  4 + "sinal": "Modelo JSON", \
106 5 "interpolacao": "normal", \
107 6 "movimentos": [ \
108 7 { \
109 8 "facial": { \
110   - "expressao": 20, \
  9 + "expressao": 10, \
111 10 "transicao": "normal", \
112 11 "duracao": "normal" \
113 12 }, \
... ... @@ -128,7 +27,7 @@ JSON = \
128 27 }, \
129 28 { \
130 29 "facial": { \
131   - "expressao": 21, \
  30 + "expressao": 11, \
132 31 "transicao": "normal", \
133 32 "duracao": "normal" \
134 33 }, \
... ...
__init__.py
... ... @@ -2,6 +2,8 @@
2 2 __all__ = (
3 3 "bmesh_collision"
4 4 "controller",
  5 + "decode",
  6 + "facial",
5 7 "libras",
6 8 "moves",
7 9 "pyutil",
... ...
decode.py
  1 +import bpy
1 2 import moves
2 3 import util
3 4  
... ... @@ -29,18 +30,30 @@ def circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand,
29 30 ik = bpy.context.object.pose.bones['ik_FK.R']
30 31 else:
31 32 ik = bpy.context.object.pose.bones['ik_FK.L']
32   - current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location'])
33   - current_frame = moves.circular(ik, current_frame + frame_jump, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular)
  33 + #current_frame = insert_keyframe_pose_default(current_frame, [ik], ['location'])
  34 + current_frame = moves.circular(ik, current_frame, ray, period, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular)
34 35 return current_frame
35 36  
36 37 def contato(js_movement, current_frame, frame_jump, is_right_hand):
37 38 sub_type = next(iter(js_movement.keys()))
38   - mov_param = js_movement[sub_type]
  39 + mov_param = js_movement[sub_type]
39 40 action = util.right_hand_actions if is_right_hand else util.left_hand_actions
40 41 bones = util.rightBonesConf if is_right_hand else util.leftBonesConf
41 42 current_frame = current_frame + 2*frame_jump
42 43 return moves.contato(action, sub_type, mov_param, bones, current_frame, frame_jump)
43 44  
  45 +def espiral(js_movement, current_frame, frame_jump, is_right_hand):
  46 + pass
  47 +
  48 +def redemoinho(js_movement, current_frame, frame_jump, is_right_hand):
  49 + pass
  50 +
  51 +def pontual(js_movement, current_frame, frame_jump, is_right_hand):
  52 + pass
  53 +
  54 +def senoidal(js_movement, current_frame, frame_jump, is_right_hand):
  55 + pass
  56 +
44 57 def hand_mov(current_frame, frame_jump, js_mao, is_right_hand):
45 58 if (js_mao == {}):
46 59 return
... ... @@ -51,4 +64,12 @@ def hand_mov(current_frame, frame_jump, js_mao, is_right_hand):
51 64 current_frame = circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True)
52 65 elif (movement_name == 'contato'):
53 66 current_frame = contato(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
54   - return current_frame + frame_jump
55 67 \ No newline at end of file
  68 + elif (movement_name == 'espiral'):
  69 + current_frame = espiral(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  70 + elif (movement_name == 'redemoinho'):
  71 + current_frame = redemoinho(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  72 + elif (movement_name == 'pontual'):
  73 + current_frame = pontual(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  74 + elif (movement_name == 'senoidal'):
  75 + current_frame = senoidal(js_mao[movement_name], current_frame, frame_jump, is_right_hand)
  76 + return current_frame + frame_jump
... ...
facial.py
... ... @@ -5,13 +5,16 @@ import util
5 5  
6 6 # duracao na posicao selecionada
7 7 dict_duration = {
  8 + 'inicial': 20,
8 9 'lento': 15,
9 10 'normal': 10,
10   - 'rapido': 5
  11 + 'rapido': 5,
  12 + 'final': 20,
11 13 }
12 14  
13 15 # tempo de entrada e saida na posicao selecionada
14 16 dict_transition = {
  17 + 'inicial': 0,
15 18 'lento': 15,
16 19 'normal': 10,
17 20 'rapido': 5
... ... @@ -59,7 +62,7 @@ def apply_pose(index = 0, pose_library = list(bpy.data.actions)):
59 62 return
60 63  
61 64 # consolida o movimento (faz insercao dos keyframes) e incrementa a timeline
62   -def set_expression(timeline_facial, index, frame_duration = dict_duration['normal'], frame_transition = 0):
  65 +def set_expression(timeline_facial, index, frame_duration = dict_duration['normal'], frame_transition = dict_transition['inicial']):
63 66 library_name = util.facial_expression_id
64 67 bones_facial = util.dict_bones[library_name]
65 68 util.select_bones(bones_facial)
... ... @@ -80,7 +83,7 @@ def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_d
80 83 global dict_transition
81 84 index = js_facial['expressao']
82 85 frame_duration = dict_duration[js_facial['duracao']]
83   - frame_transition = dict_duration[js_facial['transicao']]
  86 + frame_transition = dict_transition[js_facial['transicao']]
84 87 # insere o primeiro keyframe
85 88 if (timeline_facial == 0):
86 89 set_expression(timeline_facial, 0, initial_interpolation)
... ... @@ -91,25 +94,21 @@ def decode_expression(timeline_facial, js_facial, initial_interpolation = dict_d
91 94 """
92 95 # unit test
93 96 def main():
94   - import random
95 97 interpolation_start = 20
96 98 interpolation_end = 20
  99 + timeline_facial = 0
97 100 pose_max_range = round(bpy.data.actions[library_name].frame_range[1])
98   -
99 101 util.delete_all_keyframes()
100   - apply_pose(0, library_name)
101   -
102   - js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
103   - print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
104   -
105   - js_facial = {"expressao": random.randint(0, pose_max_range), "transicao": 'normal', "duracao": 'normal'}
106   - print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
107   -
108   - #for i in range(0, pose_max_range + 1):
109   - # js_facial = {"expressao": i, "transicao": 'normal', "duracao": 'normal'}
110   - # print('facial expression %d current frame:' % (js_facial['expressao']), decode_expression(js_facial))
111   -
112   - bpy.context.scene.frame_end = timeline_facial + interpolation_end
  102 + apply_pose(0, util.facial_expression_id)
  103 + for i in range(0, pose_max_range + 1):
  104 + js_facial = {
  105 + "expressao": i, # random.randint(0, pose_max_range),
  106 + "transicao": 'normal',
  107 + "duracao": 'normal'
  108 + }
  109 + timeline_facial = decode_expression(timeline_facial, js_facial, dict_duration['inicial'])
  110 + print('facial expression %d current frame:' % (js_facial['expressao']), timeline_facial)
  111 + bpy.context.scene.frame_end = timeline_facial + dict_duration['final']
113 112 bpy.ops.screen.animation_play(reverse = False)
114 113  
115 114 if __name__ == "__main__":
... ...
libras.py
... ... @@ -30,7 +30,7 @@ dict_interpolation = {
30 30 'final': 20
31 31 }
32 32  
33   -def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']):
  33 +def insert_keyframe_pose_default(current_frame = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']):
34 34 for obj in (pose_bones):
35 35 obj.bone.select = True
36 36 for type_keyframe in types_keyframe:
... ... @@ -39,15 +39,15 @@ def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones =
39 39 return current_frame
40 40  
41 41 def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions):
42   - result = current_frame
43 42 for action in actions:
44 43 if (action.use_fake_user):
45 44 bpy.context.object.pose_library = action
46 45 bpy.ops.poselib.apply_pose(pose_index = 0)
47   - result = insert_keyframe_pose_default(current_frame, frame_jump)
48   - return result + frame_jump
  46 + insert_keyframe_pose_default(current_frame)
  47 + return current_frame + frame_jump
49 48  
50 49 def main():
  50 + util.set_pose_mode()
51 51 util.delete_all_keyframes()
52 52 util.configure_output()
53 53 bpy.context.scene.animation_data_create()
... ... @@ -57,7 +57,7 @@ def main():
57 57 js_movimentos = js_input['movimentos']
58 58 frame_jump = dict_interpolation[js_input['interpolacao']]
59 59  
60   - endFrame = pose_default(0)
  60 + endFrame = pose_default(0, frame_jump)
61 61 timeline_mao_esquerda = 0
62 62 timeline_mao_direita = 0
63 63 timeline_facial = 0
... ... @@ -105,7 +105,9 @@ def main():
105 105 endFrame += frame_jump
106 106  
107 107 # setar pose padrao final em todos os bones (location e rotation)
108   - endFrame += pose_default(endFrame + dict_interpolation['final'])
  108 + endFrame = pose_default(endFrame, frame_jump)
  109 + endFrame += dict_interpolation['final']
  110 +
109 111 util.render_sign(js_input["userId"], js_input["sinal"], endFrame)
110 112  
111 113 except:
... ...
param.json
1 1 {
2 2 "userId": "lavid",
3   - "nome_sinal": "Modelo JSON",
4   - "velocidade_interpolacao": "lento|normal|rapido",
  3 + "sinal": "Modelo JSON",
  4 + "interpolacao": "lento|normal|rapido",
5 5 "movimentos": [
6 6 {
7 7 "facial": {
8   - "expressao": 21,
  8 + "expressao": 0..21,
  9 + "transicao": "lento|normal|rapido",
9 10 "duracao": "lento|normal|rapido"
10 11 },
11 12 "mao_esquerda": {
12   - "movimento": "semicircular",
13 13 "circular": {
14 14 "plano": "frente-esquerda|frente-cima|esquerda-cima",
15 15 "raio": "pequeno|medio|grande",
16 16 "velocidade": "lento|normal|rapido",
17   - "lado_oposto": false,
18   - "sentido_inverso": false,
19   - "articulacao": 124,
20   - "configuracao": 129,
21   - "orientacao": 142
  17 + "lado_oposto": true|false,
  18 + "sentido_inverso": true|false,
  19 + "articulacao": 0..124,
  20 + "configuracao": 0..59,
  21 + "orientacao": 0..142
22 22 },
23 23 "semicircular": {
24 24 "plano": "frente-esquerda|frente-cima|esquerda-cima",
25 25 "raio": "pequeno|medio|grande",
26   - "velocidade": "lento|normal|rapido",
27   - "lado_oposto": false,
28   - "sentido_inverso": false,
29   - "articulacao": 124,
30   - "configuracao": 129,
31   - "orientacao": 142
  26 + "lado_oposto": true|false,
  27 + "sentido_inverso": true|false,
  28 + "articulacao": 0..124,
  29 + "configuracao": 0..59,
  30 + "orientacao": 0..142
32 31 },
33 32 "contato": {
34 33 "alisar": {
35 34 "movimento_orientacao": "perpendicular|paralelo|diagonal-direita|diagonal-esquerda",
36   - "articulacao": 124,
37   - "configuracao": 129,
38   - "orientacao": 142
  35 + "articulacao": 0..124,
  36 + "configuracao": 0..59,
  37 + "orientacao": 0..142
39 38 },
40 39 "cocar": {
41   - "articulacao": 124,
42   - "configuracao": 129,
43   - "orientacao": 142
  40 + "articulacao": 0..124,
  41 + "configuracao": 0..59,
  42 + "orientacao": 0..142
44 43 },
45 44 "tocar": {
46   - "articulacao": 124,
47   - "configuracao": 129,
48   - "orientacao": 142
  45 + "articulacao": 0..124,
  46 + "configuracao": 0..59,
  47 + "orientacao": 0..142
49 48 },
50 49 "riscar": {
51   - "articulacao": 124,
52   - "configuracao": 129,
53   - "orientacao": 142
  50 + "articulacao": 0..124,
  51 + "configuracao": 0..59,
  52 + "orientacao": 0..142
54 53 }
55 54 },
56   - "contato_sugestao": {
57   - "tipo": "cocar|riscar|tocar",
58   - "mov_orientacao": "perpendicular|paralelo|diagonal-direita|diagonal-esquerda",
59   - "articulacao": 124,
60   - "configuracao": 129,
61   - "orientacao": 142
62   - },
63 55 "espiral": {
64 56 "plano": "frente-esquerda|frente-cima|esquerda-cima",
65 57 "raio": "pequeno|medio|grande",
66   - "lado_oposto": false,
67   - "sentido_inverso": false,
68   - "articulacao": 124,
69   - "configuracao": 129,
70   - "orientacao": 142
  58 + "lado_oposto": true|false,
  59 + "sentido_inverso": true|false,
  60 + "articulacao": 0..124,
  61 + "configuracao": 0..59,
  62 + "orientacao": 0..142
71 63 },
72 64 "helicoidal": {
73 65 "plano": "frente-esquerda|frente-cima|esquerda-cima",
74 66 "raio": "pequeno|medio|grande",
75   - "lado_oposto": false,
76   - "sentido_inverso": false,
77   - "articulacao": 124,
78   - "configuracao": 129,
79   - "orientacao": 142
  67 + "lado_oposto": true|false,
  68 + "sentido_inverso": true|false,
  69 + "articulacao": 0..124,
  70 + "configuracao": 0..59,
  71 + "orientacao": 0..142
80 72 },
81 73 "pontual": {
82   - "articulacao": 124,
83   - "configuracao": 129,
84   - "orientacao": 142
  74 + "transicao": "lento|normal|rapido",
  75 + "duracao": "lento|normal|rapido"
  76 + "articulacao": 0..124,
  77 + "configuracao": 0..59,
  78 + "orientacao": 0..142
85 79 },
86 80 "retilineo": {
87   - "articulacao_inicial": 124,
88   - "articulacao_final": 124,
89   - "configuracao": 129,
90   - "orientacao": 142
  81 + "transicao": "lento|normal|rapido",
  82 + "duracao": "lento|normal|rapido",
  83 + "articulacao_inicial": 0..124,
  84 + "articulacao_final": 0..124,
  85 + "configuracao": 0..59,
  86 + "orientacao": 0..142
91 87 },
92 88 "senoidal": {
93 89 "direcao": "frente|esquerda|cima",
94   - "direcao_oposta": false,
  90 + "direcao_oposta": true|false,
95 91 "eixo_fixo": "frente-tras|esquerda-direita|cima-baixo",
96 92 "comprimento_onda": "pequeno|medio|grande",
97   - "articulacao": 124,
98   - "configuracao": 129,
99   - "orientacao": 142
  93 + "articulacao": 0..124,
  94 + "configuracao": 0..59,
  95 + "orientacao": 0..142
100 96 }
101 97 },
102 98 "mao_direita": {
103 99 }
104   - },
105   - {
106 100 }
107 101 ]
108 102 }
... ...
util.py
... ... @@ -2,10 +2,10 @@
2 2  
3 3 import bpy
4 4 import math
5   -import pyutil
6 5 import os
7 6 import sys
8 7 import copy
  8 +import pyutil
9 9 from bmesh_collision import bmesh_check_intersect_objects
10 10  
11 11 armature = bpy.context.scene.objects.get('Armature.001')
... ... @@ -71,10 +71,12 @@ def deselect_bones(bones = bpy.context.object.pose.bones):
71 71 pose_bone.bone.select = False
72 72 return
73 73  
74   -def delete_all_keyframes():
  74 +def set_pose_mode():
75 75 bpy.ops.object.mode_set(mode = 'OBJECT')
76 76 bpy.ops.object.select_all(action = "DESELECT")
77 77 bpy.ops.object.mode_set(mode = 'POSE')
  78 +
  79 +def delete_all_keyframes():
78 80 bpy.context.active_object.animation_data_clear()
79 81 for obj in bpy.data.objects:
80 82 obj.animation_data_clear()
... ... @@ -116,7 +118,7 @@ def resetIKPosition(isRightHand):
116 118 def resetBnMaoPosition(isRightHand):
117 119 armature.pose_library = bpy.data.actions[orient_direita_id if isRightHand else orient_esquerda_id]
118 120 bpy.ops.poselib.apply_pose(pose_index = 0)
119   -
  121 +
120 122 def get_bone_data_from_frame(bone, positionFrame, path):
121 123 scene = bpy.context.scene
122 124 frame_current = scene.frame_current
... ... @@ -164,7 +166,7 @@ def check_collision(objName, otherObjName, initFrame, endFrame):
164 166 frame_current = scene.frame_current
165 167 startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2))
166 168 collisionFrame = -1
167   -
  169 +
168 170 for i in range(startFrame, endFrame + 1, 1):
169 171 scene.frame_set(i)
170 172 obj = scene.objects.get(objName)
... ...