Commit 8425c440950ffd24937356e04b947a1ea0bb4830
1 parent
9b7b787e
Exists in
master
Altera código para formato JSON mais recente
Showing
6 changed files
with
348 additions
and
113 deletions
Show diff stats
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 | + "velocidade": "lento|normal|rapido" \ | ||
| 11 | + }, \ | ||
| 12 | + "mao_esquerda": { \ | ||
| 13 | + "circular": { \ | ||
| 14 | + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ | ||
| 15 | + "raio": "pequeno|medio|grande", \ | ||
| 16 | + "velocidade": "lento|normal|rapido", \ | ||
| 17 | + "lado_oposto": true|false, \ | ||
| 18 | + "sentido_inverso": true|false, \ | ||
| 19 | + "articulacao": 0..124, \ | ||
| 20 | + "configuracao": 0..60, \ | ||
| 21 | + "orientacao": 0..142 \ | ||
| 22 | + }, \ | ||
| 23 | + "semicircular": { \ | ||
| 24 | + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ | ||
| 25 | + "raio": "pequeno|medio|grande", \ | ||
| 26 | + "lado_oposto": true|false, \ | ||
| 27 | + "sentido_inverso": true|false, \ | ||
| 28 | + "articulacao": 0..124, \ | ||
| 29 | + "configuracao": 0..60, \ | ||
| 30 | + "orientacao": 0..142 \ | ||
| 31 | + }, \ | ||
| 32 | + "contato": { \ | ||
| 33 | + "alisar": { \ | ||
| 34 | + "movimento_orientacao": "perpendicular|paralelo|diagonal-direita|diagonal-esquerda", \ | ||
| 35 | + "articulacao": 0..124, \ | ||
| 36 | + "configuracao": 0..60, \ | ||
| 37 | + "orientacao": 0..142 \ | ||
| 38 | + }, \ | ||
| 39 | + "cocar": { \ | ||
| 40 | + "articulacao": 0..124, \ | ||
| 41 | + "configuracao": 0..60, \ | ||
| 42 | + "orientacao": 0..142 \ | ||
| 43 | + }, \ | ||
| 44 | + "tocar": { \ | ||
| 45 | + "articulacao": 0..124, \ | ||
| 46 | + "configuracao": 0..60, \ | ||
| 47 | + "orientacao": 0..142 \ | ||
| 48 | + }, \ | ||
| 49 | + "riscar": { \ | ||
| 50 | + "articulacao": 0..124, \ | ||
| 51 | + "configuracao": 0..60, \ | ||
| 52 | + "orientacao": 0..142 \ | ||
| 53 | + } \ | ||
| 54 | + }, \ | ||
| 55 | + "espiral": { \ | ||
| 56 | + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ | ||
| 57 | + "raio": "pequeno|medio|grande", \ | ||
| 58 | + "lado_oposto": true|false, \ | ||
| 59 | + "sentido_inverso": true|false, \ | ||
| 60 | + "articulacao": 0..124, \ | ||
| 61 | + "configuracao": 0..60, \ | ||
| 62 | + "orientacao": 0..142 \ | ||
| 63 | + }, \ | ||
| 64 | + "helicoidal": { \ | ||
| 65 | + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ | ||
| 66 | + "raio": "pequeno|medio|grande", \ | ||
| 67 | + "lado_oposto": true|false, \ | ||
| 68 | + "sentido_inverso": true|false, \ | ||
| 69 | + "articulacao": 0..124, \ | ||
| 70 | + "configuracao": 0..60, \ | ||
| 71 | + "orientacao": 0..142 \ | ||
| 72 | + }, \ | ||
| 73 | + "pontual": { \ | ||
| 74 | + "articulacao": 0..124, \ | ||
| 75 | + "configuracao": 0..60, \ | ||
| 76 | + "orientacao": 0..142 \ | ||
| 77 | + }, \ | ||
| 78 | + "retilineo": { \ | ||
| 79 | + "velocidade": "lento|normal|rapido", \ | ||
| 80 | + "articulacao_inicial": 0..124, \ | ||
| 81 | + "articulacao_final": 0..124, \ | ||
| 82 | + "configuracao": 0..60, \ | ||
| 83 | + "orientacao": 0..142 \ | ||
| 84 | + }, \ | ||
| 85 | + "senoidal": { \ | ||
| 86 | + "direcao": "frente|esquerda|cima", \ | ||
| 87 | + "direcao_oposta": true|false, \ | ||
| 88 | + "eixo_fixo": "frente-tras|esquerda-direita|cima-baixo", \ | ||
| 89 | + "comprimento_onda": "pequeno|medio|grande", \ | ||
| 90 | + "articulacao": 0..124, \ | ||
| 91 | + "configuracao": 0..60, \ | ||
| 92 | + "orientacao": 0..142 \ | ||
| 93 | + } \ | ||
| 94 | + }, \ | ||
| 95 | + "mao_direita": { \ | ||
| 96 | + } \ | ||
| 97 | + } \ | ||
| 98 | + ] \ | ||
| 99 | +}' | ||
| 100 | + | ||
| 101 | +JSON = \ | ||
| 102 | +'{ \ | ||
| 103 | + "userId": "lavid", \ | ||
| 104 | + "sinal": "Modelo JSON 2", \ | ||
| 105 | + "ex_interpolacao": "lento|normal|rapido", \ | ||
| 106 | + "interpolacao": "normal", \ | ||
| 107 | + "movimentos": [ \ | ||
| 108 | + { \ | ||
| 109 | + "facial": { \ | ||
| 110 | + "expressao": 21, \ | ||
| 111 | + "velocidade": "lento|normal|rapido" \ | ||
| 112 | + }, \ | ||
| 113 | + "mao_esquerda": { \ | ||
| 114 | + "circular": { \ | ||
| 115 | + "plano": "esquerda-cima", \ | ||
| 116 | + "raio": "pequeno", \ | ||
| 117 | + "velocidade": "lento", \ | ||
| 118 | + "lado_oposto": false, \ | ||
| 119 | + "sentido_inverso": false, \ | ||
| 120 | + "articulacao": 124, \ | ||
| 121 | + "configuracao": 129, \ | ||
| 122 | + "orientacao": 142 \ | ||
| 123 | + } \ | ||
| 124 | + }, \ | ||
| 125 | + "mao_direita": { \ | ||
| 126 | + } \ | ||
| 127 | + } \ | ||
| 128 | + ] \ | ||
| 129 | +}' | ||
| 130 | + | ||
| 1 | BLEND = avatar_cartoon_v2.74.blend | 131 | BLEND = avatar_cartoon_v2.74.blend |
| 2 | CONTROLLER = controller.py | 132 | CONTROLLER = controller.py |
| 3 | MAIN = libras.py | 133 | MAIN = libras.py |
| 4 | -# Circular: ['circular', x, x, Raio=1, Voltas=3 CfM=0, PAr=80, Ori=0] | ||
| 5 | -JSON = '{"userId": 4, "rightHand": ["circular", "plano", "horario", 1, 3, 0, 80, 0], "leftHand":[], "facialExp": [1], "signName": "teste circular"}' | ||
| 6 | -#JSON = '{"userId": 4, "rightHand": ["pontual", 55, 81, 21], "leftHand":[], "facialExp": [], "signName": "teste pontual"}' | ||
| 7 | -#JSON = '{"userId": 4, "rightHand": ["pontual", 0, 80, 1], "leftHand":[], "facialExp": [1], "signName": "teste facial 1"}' | ||
| 8 | -#JSON = '{"userId": 4, "rightHand": ["pontual", 0, 80, 2], "leftHand":[], "facialExp": [21], "signName": "teste facial 2"}' | ||
| 9 | BLENDER = blender | 134 | BLENDER = blender |
| 10 | CACHE += "./__pycache__" | 135 | CACHE += "./__pycache__" |
| 11 | CACHE += "./users" | 136 | CACHE += "./users" |
controller.py
| 1 | # -*- coding: UTF-8 -*- | 1 | # -*- coding: UTF-8 -*- |
| 2 | 2 | ||
| 3 | -from subprocess import call | ||
| 4 | -from sys import argv | ||
| 5 | -from os.path import abspath, dirname, join | 3 | +import subprocess |
| 4 | +import sys | ||
| 5 | +import os | ||
| 6 | 6 | ||
| 7 | -getcwd = dirname(abspath(__file__)) | 7 | +getcwd = os.path.dirname(os.path.abspath(__file__)) |
| 8 | 8 | ||
| 9 | -from pyutil import printStackTrace | 9 | +import pyutil |
| 10 | + | ||
| 11 | +blend_path = os.path.join(getcwd, "avatar_cartoon_v2.74.blend") | ||
| 12 | +main_path = os.path.join(getcwd, "libras.py") | ||
| 10 | 13 | ||
| 11 | -blend_path = join(getcwd, "avatar_cartoon_v2.74.blend") | ||
| 12 | -main_path = join(getcwd, "libras.py") | ||
| 13 | result = 0 | 14 | result = 0 |
| 14 | 15 | ||
| 15 | try: | 16 | try: |
| 16 | - # Caso seja necessário gravar logs do blender utilizar a linha de código abaixo | ||
| 17 | - # result = call(['blender', '-b', blend_path, '-P', main_path, '--', argv[1]], stdout = open('bpy.log', 'w')) | ||
| 18 | - result = call(['blender', '-b', blend_path, '-P', main_path, '--', argv[1]]) | 17 | + # para gravar logs do blender, usar codigo abaixo |
| 18 | + # result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]], stdout = open('bpy.log', 'w')) | ||
| 19 | + result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]]) | ||
| 19 | except: | 20 | except: |
| 20 | - result = printStackTrace(__file__) | 21 | + result = pyutil.printStackTrace(__file__) |
| 21 | 22 | ||
| 22 | exit(result) | 23 | exit(result) |
libras.py
| @@ -5,71 +5,111 @@ import bpy | @@ -5,71 +5,111 @@ import bpy | ||
| 5 | 5 | ||
| 6 | # importa modulos do Python | 6 | # importa modulos do Python |
| 7 | import json | 7 | import json |
| 8 | -from sys import argv, path | ||
| 9 | -from os.path import abspath, dirname | 8 | +import sys |
| 9 | +import os | ||
| 10 | 10 | ||
| 11 | -# define o caminho absoluto do diretório deste arquivo | ||
| 12 | -getcwd = dirname(abspath(__file__)) | 11 | +# define o caminho absoluto do diretorio deste arquivo |
| 12 | +getcwd = os.path.dirname(os.path.abspath(__file__)) | ||
| 13 | 13 | ||
| 14 | # insere o caminho do diretorio atual no path (permite o acesso aos modulos locais) | 14 | # insere o caminho do diretorio atual no path (permite o acesso aos modulos locais) |
| 15 | -path.insert(0, getcwd) | 15 | +sys.path.insert(0, getcwd) |
| 16 | 16 | ||
| 17 | # importa modulos locais | 17 | # importa modulos locais |
| 18 | -import util, moves | ||
| 19 | -from pyutil import printStackTrace | ||
| 20 | - | ||
| 21 | -# tenta decodificar o argumento JSON recebido | ||
| 22 | -try: | ||
| 23 | - json_input = json.loads(argv[6]) | ||
| 24 | -except Exception: | ||
| 25 | - printStackTrace(__file__) | ||
| 26 | - exit(1) | ||
| 27 | - | ||
| 28 | -# ajusta as configurações de renderização | ||
| 29 | -util.outconf() | ||
| 30 | - | ||
| 31 | -# Cria uma Action | ||
| 32 | -act = bpy.context.scene.animation_data_create() | ||
| 33 | - | ||
| 34 | -# Função responsável por setar pose padrão | ||
| 35 | -def poseDefault(positionFrames, collisionFlag = False): | 18 | +import util |
| 19 | +import moves | ||
| 20 | +import pyutil | ||
| 21 | + | ||
| 22 | +# intervalos de interpolacao dos keyframes | ||
| 23 | +interpolation = {'inicial': 20, 'lento': 5, 'normal': 10, 'rapido': 15, 'final': 20} | ||
| 24 | + | ||
| 25 | +def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']): | ||
| 26 | + for obj in (pose_bones): | ||
| 27 | + obj.bone.select = True | ||
| 28 | + for type_keyframe in types_keyframe: | ||
| 29 | + obj.keyframe_insert(index = -1, frame = current_frame, group = obj.name, data_path = type_keyframe) | ||
| 30 | + obj.bone.select = False | ||
| 31 | + return current_frame + frame_jump | ||
| 32 | + | ||
| 33 | +def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions): | ||
| 34 | + result = 0 | ||
| 35 | + for action in actions: | ||
| 36 | + if (action.use_fake_user): | ||
| 37 | + bpy.context.object.pose_library = action | ||
| 38 | + bpy.ops.poselib.apply_pose(pose_index = 0) | ||
| 39 | + result = insert_keyframe_pose_default(current_frame, frame_jump) | ||
| 40 | + return result | ||
| 41 | + | ||
| 42 | +def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular): | ||
| 43 | + # const | ||
| 44 | + obj_raio = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5} | ||
| 45 | + obj_periodo = {'lento': 55, 'normal': 45, 'rapido': 35} | ||
| 46 | + # decodificar valores | ||
| 47 | + raio = obj_raio[js_movement['raio']] | ||
| 48 | + periodo = obj_periodo[js_movement['velocidade']] | ||
| 49 | + # diminuir a velocidade | ||
| 50 | + if (js_movement['velocidade'] == 'lento'): | ||
| 51 | + periodo += 10 | ||
| 52 | + # aumentar a velocidade | ||
| 53 | + elif (js_movement['velocidade'] == 'rapido'): | ||
| 54 | + periodo -= 10 | ||
| 55 | + # definir eixos do movimento | ||
| 56 | + if (js_movement['plano'] == 'frente-esquerda'): | ||
| 57 | + x, y = 2, 0 | ||
| 58 | + elif (js_movement['plano'] == 'frente-cima'): | ||
| 59 | + x, y = 2, 1 | ||
| 60 | + else: | ||
| 61 | + x, y = 0, 1 | ||
| 62 | + # mao usada (direita/esquerda) | ||
| 63 | + if (is_right_hand): | ||
| 64 | + ik = bpy.context.object.pose.bones[1] | ||
| 65 | + else: | ||
| 66 | + ik = bpy.context.object.pose.bones[0] | ||
| 67 | + current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location']) | ||
| 68 | + current_frame = moves.circular(ik, current_frame + frame_jump, raio, periodo, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular) | ||
| 69 | + return current_frame | ||
| 70 | + | ||
| 71 | +def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand): | ||
| 72 | + if (js_mao == {}): | ||
| 73 | + return | ||
| 74 | + movement_name = next(iter(js_mao.keys())) | ||
| 75 | + print("Movimento: " + movement_name) | ||
| 76 | + if (movement_name == 'circular'): | ||
| 77 | + current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, False) | ||
| 78 | + elif (movement_name == 'semicircular'): | ||
| 79 | + current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True) | ||
| 80 | + return current_frame + frame_jump | ||
| 81 | + | ||
| 82 | +# Funcao responsavel por setar pose padrao | ||
| 83 | +def poseDefault(json_input, positionFrames, collisionFlag = False): | ||
| 36 | handDefaultParam = [0, 0, 0] | 84 | handDefaultParam = [0, 0, 0] |
| 37 | util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag) | 85 | util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag) |
| 38 | if(json_input["leftHand"] != []): | 86 | if(json_input["leftHand"] != []): |
| 39 | util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag) | 87 | util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag) |
| 40 | #setFaceConfiguration([0], positionFrames, util.faceBonesConf) | 88 | #setFaceConfiguration([0], positionFrames, util.faceBonesConf) |
| 41 | 89 | ||
| 42 | -# Função responsável por setar as configurações das mãos | 90 | +# Funcao responsavel por setar as configuracoes das maos |
| 43 | def setHandConfiguration(actions, handParam, positionFrames, bones): | 91 | def setHandConfiguration(actions, handParam, positionFrames, bones): |
| 44 | util.setPose(actions, handParam, positionFrames, bones) | 92 | util.setPose(actions, handParam, positionFrames, bones) |
| 45 | 93 | ||
| 46 | -# Função responsável por setar a configuração da face | 94 | +# Funcao responsavel por setar a configuracao da face |
| 47 | def setFaceConfiguration(handParam, positionFrames, bones): | 95 | def setFaceConfiguration(handParam, positionFrames, bones): |
| 48 | util.setPose(util.facial_expression_action, handParam, positionFrames, bones) | 96 | util.setPose(util.facial_expression_action, handParam, positionFrames, bones) |
| 49 | 97 | ||
| 50 | -# Sugestao: Alguma forma de uniformizar o calculo do endFrame (atualizado aqui e no movimento circular) | ||
| 51 | -initialFrame, endFrame = 15, util.get_endFrame(json_input, util.hands_frames_retilineo) | ||
| 52 | - | ||
| 53 | -#------------------ Configurações------------------------------ | ||
| 54 | - | ||
| 55 | -#Função que inicia a configuração de ambas as mãos | ||
| 56 | -def configureHands(): | ||
| 57 | - # Array com valores dos campos que serão passados pelo JSON | 98 | +#Funcao que inicia a configuracao de ambas as maos |
| 99 | +def configureHands(endFrame): | ||
| 100 | + # Array com valores dos campos que serao passados pelo JSON | ||
| 58 | hands = ["rightHand", "leftHand"] | 101 | hands = ["rightHand", "leftHand"] |
| 59 | iks = ["ik_FK.R", "ik_FK.L"] | 102 | iks = ["ik_FK.R", "ik_FK.L"] |
| 60 | bones_ = [util.rightBonesConf, util.leftBonesConf] | 103 | bones_ = [util.rightBonesConf, util.leftBonesConf] |
| 61 | # Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo | 104 | # Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo |
| 62 | actions = [util.right_hand_actions, util.left_hand_actions] | 105 | actions = [util.right_hand_actions, util.left_hand_actions] |
| 63 | - global endFrame | ||
| 64 | for i in range(len(hands)): | 106 | for i in range(len(hands)): |
| 65 | if(json_input[hands[i]] != []): | 107 | if(json_input[hands[i]] != []): |
| 66 | move = json_input[hands[i]][0] | 108 | move = json_input[hands[i]][0] |
| 67 | pose = util.armature.pose.bones[iks[i]] | 109 | pose = util.armature.pose.bones[iks[i]] |
| 68 | handParam = json_input[hands[i]][-3:] | 110 | handParam = json_input[hands[i]][-3:] |
| 69 | - | ||
| 70 | if(move in ["pontual", "circular", "semicircular", "retilineo", "senoidal"]): | 111 | if(move in ["pontual", "circular", "semicircular", "retilineo", "senoidal"]): |
| 71 | setHandConfiguration(actions[i], handParam, util.hands_default_frames, bones_[i]) | 112 | setHandConfiguration(actions[i], handParam, util.hands_default_frames, bones_[i]) |
| 72 | - | ||
| 73 | if(move in ["circular", "semicircular"]): | 113 | if(move in ["circular", "semicircular"]): |
| 74 | orientation, direction, radius, laps = json_input[hands[i]][1:5] | 114 | orientation, direction, radius, laps = json_input[hands[i]][1:5] |
| 75 | #endFrame = moves.circular_or_semiCircular(pose, orientation, direction, radius, laps, 5) | 115 | #endFrame = moves.circular_or_semiCircular(pose, orientation, direction, radius, laps, 5) |
| @@ -84,20 +124,71 @@ def configureHands(): | @@ -84,20 +124,71 @@ def configureHands(): | ||
| 84 | elif(move == "contato"): | 124 | elif(move == "contato"): |
| 85 | endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose) | 125 | endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose) |
| 86 | 126 | ||
| 87 | -# Função que inicia a configuração da face | ||
| 88 | -def configureFace(): | ||
| 89 | - global endFrame | ||
| 90 | - if(json_input["facialExp"] != []): | ||
| 91 | - setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) | 127 | +# Funcao que inicia a configuracao da face |
| 128 | +def setFacialExpr(a, b): | ||
| 129 | + pass | ||
| 130 | + #if(json_input["facialExp"] != []): | ||
| 131 | + # setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) | ||
| 92 | 132 | ||
| 93 | def main(): | 133 | def main(): |
| 94 | - poseDefault([1]) | ||
| 95 | - configureHands() | ||
| 96 | - configureFace() | ||
| 97 | - poseDefault([endFrame + 15]) | ||
| 98 | - # Default Pose | ||
| 99 | - print("Total frames: %.3i" % (endFrame)) | ||
| 100 | - util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25) | 134 | + util.configure_output() |
| 135 | + bpy.context.scene.animation_data_create() | ||
| 136 | + | ||
| 137 | + try: | ||
| 138 | + js_input = json.loads(sys.argv[6]) | ||
| 139 | + js_movimentos = js_input['movimentos'] | ||
| 140 | + frame_jump = interpolation[js_input['interpolacao']] | ||
| 141 | + | ||
| 142 | + endFrame = pose_default(0) | ||
| 143 | + facial_frame = 0 | ||
| 144 | + mao_esquerda_frame = 0 | ||
| 145 | + mao_direita_frame = 0 | ||
| 146 | + | ||
| 147 | + # setar pose padrao inicial em todos os bones ('location' e 'rotation_quaternion') | ||
| 148 | + endFrame += pose_default(interpolation['inicial']) | ||
| 149 | + | ||
| 150 | + for i in range(0, len(js_movimentos)): | ||
| 151 | + | ||
| 152 | + js_facial = js_movimentos[i]['facial'] | ||
| 153 | + | ||
| 154 | + if (js_facial != {}): | ||
| 155 | + setFacialExpr(js_facial['expressao'], js_facial['velocidade']) | ||
| 156 | + else: | ||
| 157 | + pyutil.log("<Vazio> Expressao Facial %d" % (i)) | ||
| 158 | + | ||
| 159 | + js_mao_esquerda = js_movimentos[i]['mao_esquerda'] | ||
| 160 | + if (js_mao_esquerda != {}): | ||
| 161 | + mao_esquerda_frame += decode_hand_mov(mao_esquerda_frame, frame_jump, js_mao_esquerda, False) | ||
| 162 | + else: | ||
| 163 | + pyutil.log("<Vazio> mov %d Mao esquerda" % (i)) | ||
| 164 | + | ||
| 165 | + js_mao_direita = js_movimentos[i]['mao_direita'] | ||
| 166 | + if (js_mao_direita != {}): | ||
| 167 | + mao_direita_frame += decode_hand_mov(mao_direita_frame, frame_jump, js_mao_direita, True) | ||
| 168 | + else: | ||
| 169 | + pyutil.log("<Vazio> mov %d Mao direita" % (i)) | ||
| 170 | + | ||
| 171 | + endFrame = max(facial_frame, mao_esquerda_frame, mao_direita_frame) | ||
| 172 | + endFrame += frame_jump | ||
| 173 | + | ||
| 174 | + # setar pose padrao final em todos os bones (location e rotation) | ||
| 175 | + #endFrame += pose_default(endFrame + interpolation['final']) | ||
| 176 | + endFrame = insert_keyframe_pose_default(endFrame, frame_jump) | ||
| 177 | + endFrame += interpolation['final'] | ||
| 178 | + | ||
| 179 | + # Sugestao: Alguma forma de uniformizar o calculo do endFrame (atualizado aqui e no movimento circular) | ||
| 180 | + #initialFrame = 15 | ||
| 181 | + #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo) | ||
| 182 | + #poseDefault([1]) | ||
| 183 | + #configureHands(endFrame) | ||
| 184 | + #configureFace(endFrame) | ||
| 185 | + #poseDefault(js_input, [endFrame + 15]) | ||
| 186 | + | ||
| 187 | + util.render_sign(js_input["userId"], js_input["sinal"], endFrame) | ||
| 188 | + | ||
| 189 | + except: | ||
| 190 | + pyutil.printStackTrace(__file__) | ||
| 191 | + raise | ||
| 101 | 192 | ||
| 102 | if __name__ == "__main__": | 193 | if __name__ == "__main__": |
| 103 | main() | 194 | main() |
moves.py
| @@ -159,14 +159,14 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi | @@ -159,14 +159,14 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi | ||
| 159 | # raio: "grande" raio = 1.5, velocidade: "normal" periodo = 55 | 159 | # raio: "grande" raio = 1.5, velocidade: "normal" periodo = 55 |
| 160 | # raio: "grande" raio = 1.5, velocidade: "lento" periodo = 65 | 160 | # raio: "grande" raio = 1.5, velocidade: "lento" periodo = 65 |
| 161 | # @param obj: (objeto) bone, mesh, e.g. | 161 | # @param obj: (objeto) bone, mesh, e.g. |
| 162 | -# @param itFrame: (int) posicao onde o primeiro keyframe vai ser inserido | 162 | +# @param frame_atual: (int) posicao onde o primeiro keyframe vai ser inserido |
| 163 | # @param raio: (int) raio da circunferencia | 163 | # @param raio: (int) raio da circunferencia |
| 164 | # @param periodo: (int) quantidade de keyframes necessarios para completar uma volta completa | 164 | # @param periodo: (int) quantidade de keyframes necessarios para completar uma volta completa |
| 165 | # @param x: (int) in [0,1,2] define qual eixo vai variar no seno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) | 165 | # @param x: (int) in [0,1,2] define qual eixo vai variar no seno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) |
| 166 | # @param y: (int) in [0,1,2] define qual eixo vai variar no cosseno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) | 166 | # @param y: (int) in [0,1,2] define qual eixo vai variar no cosseno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) |
| 167 | -# @param ladoOposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar) | ||
| 168 | -# @param inverterDirecao (bool) inverte o sentido do movimento (horario para anti-horario) | ||
| 169 | -def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inverterDirecao = False): | 167 | +# @param usar_lado_oposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar) |
| 168 | +# @param usar_sentido_oposto (bool) inverte o sentido do movimento (horario para anti-horario) | ||
| 169 | +def circular(obj, frame_atual, raio, periodo, x = 0, y = 1, usar_lado_oposto = False, usar_sentido_oposto = False, meia_volta = False): | ||
| 170 | # limita inferiormente | 170 | # limita inferiormente |
| 171 | if (periodo < 16): | 171 | if (periodo < 16): |
| 172 | periodo = 16 | 172 | periodo = 16 |
| @@ -174,7 +174,7 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve | @@ -174,7 +174,7 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve | ||
| 174 | elif (periodo > 360): | 174 | elif (periodo > 360): |
| 175 | periodo = 360 | 175 | periodo = 360 |
| 176 | # muda lado inicial | 176 | # muda lado inicial |
| 177 | - if (ladoOposto): | 177 | + if (usar_lado_oposto): |
| 178 | k = round(periodo / 2) | 178 | k = round(periodo / 2) |
| 179 | else: | 179 | else: |
| 180 | k = 0 | 180 | k = 0 |
| @@ -182,17 +182,22 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve | @@ -182,17 +182,22 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve | ||
| 182 | x %= 3 | 182 | x %= 3 |
| 183 | y %= 3 | 183 | y %= 3 |
| 184 | # inverte direcao do movimento | 184 | # inverte direcao do movimento |
| 185 | - if (inverterDirecao): | 185 | + if (usar_sentido_oposto): |
| 186 | tmp = x | 186 | tmp = x |
| 187 | x = y | 187 | x = y |
| 188 | y = tmp | 188 | y = tmp |
| 189 | # copia posicao inicial para transladar | 189 | # copia posicao inicial para transladar |
| 190 | loc = [obj.location[0], obj.location[1], obj.location[2]] | 190 | loc = [obj.location[0], obj.location[1], obj.location[2]] |
| 191 | - for i in range(k, periodo + k): | ||
| 192 | - # pequena otimizacao para reduzir a quantidade de keyframes | ||
| 193 | - if (itFrame % 2 == 0): | 191 | + # semi-circular |
| 192 | + limite = periodo + k | ||
| 193 | + if (meia_volta): | ||
| 194 | + limite = round(limite / 2) | ||
| 195 | + for i in range(k, limite + 1): | ||
| 196 | + # reduz a quantidade de keyframes | ||
| 197 | + if (frame_atual % 2 == 0): | ||
| 194 | obj.location[x] = loc[x] + (raio * math.cos(i / periodo * (2 * math.pi))) | 198 | obj.location[x] = loc[x] + (raio * math.cos(i / periodo * (2 * math.pi))) |
| 195 | obj.location[y] = loc[y] + (raio * math.sin(i / periodo * (2 * math.pi))) | 199 | obj.location[y] = loc[y] + (raio * math.sin(i / periodo * (2 * math.pi))) |
| 196 | - util.keyframe_insert(obj, 'location', itFrame) | ||
| 197 | - itFrame += 1 | 200 | + util.keyframe_insert(obj, 'location', frame_atual) |
| 201 | + frame_atual += 1 | ||
| 202 | + util.keyframe_insert(obj, 'location', frame_atual) | ||
| 198 | return periodo - 1 | 203 | return periodo - 1 |
param.json
| @@ -13,6 +13,7 @@ | @@ -13,6 +13,7 @@ | ||
| 13 | "circular": { | 13 | "circular": { |
| 14 | "plano": "frente-esquerda|frente-cima|esquerda-cima", | 14 | "plano": "frente-esquerda|frente-cima|esquerda-cima", |
| 15 | "raio": "pequeno|medio|grande", | 15 | "raio": "pequeno|medio|grande", |
| 16 | + "velocidade": "lento|normal|rapido", | ||
| 16 | "lado_oposto": false, | 17 | "lado_oposto": false, |
| 17 | "sentido_inverso": false, | 18 | "sentido_inverso": false, |
| 18 | "articulacao": 124, | 19 | "articulacao": 124, |
| @@ -22,6 +23,7 @@ | @@ -22,6 +23,7 @@ | ||
| 22 | "semicircular": { | 23 | "semicircular": { |
| 23 | "plano": "frente-esquerda|frente-cima|esquerda-cima", | 24 | "plano": "frente-esquerda|frente-cima|esquerda-cima", |
| 24 | "raio": "pequeno|medio|grande", | 25 | "raio": "pequeno|medio|grande", |
| 26 | + "velocidade": "lento|normal|rapido", | ||
| 25 | "lado_oposto": false, | 27 | "lado_oposto": false, |
| 26 | "sentido_inverso": false, | 28 | "sentido_inverso": false, |
| 27 | "articulacao": 124, | 29 | "articulacao": 124, |
| @@ -82,8 +84,8 @@ | @@ -82,8 +84,8 @@ | ||
| 82 | "orientacao": 142 | 84 | "orientacao": 142 |
| 83 | }, | 85 | }, |
| 84 | "retilineo": { | 86 | "retilineo": { |
| 85 | - "articulacao_inicial_id": 124, | ||
| 86 | - "articulacao_final_id": 124, | 87 | + "articulacao_inicial": 124, |
| 88 | + "articulacao_final": 124, | ||
| 87 | "configuracao": 129, | 89 | "configuracao": 129, |
| 88 | "orientacao": 142 | 90 | "orientacao": 142 |
| 89 | }, | 91 | }, |
util.py
| @@ -2,6 +2,9 @@ | @@ -2,6 +2,9 @@ | ||
| 2 | 2 | ||
| 3 | import bpy | 3 | import bpy |
| 4 | import math | 4 | import math |
| 5 | +import pyutil | ||
| 6 | +import os | ||
| 7 | +import sys | ||
| 5 | from bmesh_collision import bmesh_check_intersect_objects | 8 | from bmesh_collision import bmesh_check_intersect_objects |
| 6 | 9 | ||
| 7 | armature = bpy.context.scene.objects.get('Armature.001') | 10 | armature = bpy.context.scene.objects.get('Armature.001') |
| @@ -47,12 +50,26 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id] | @@ -47,12 +50,26 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id] | ||
| 47 | 50 | ||
| 48 | last_keyframe_dict = {} | 51 | last_keyframe_dict = {} |
| 49 | 52 | ||
| 53 | +def select_bones(bones = None): | ||
| 54 | + if (isinstance(bones, int)): | ||
| 55 | + bpy.context.object.pose.bones[bones].bone.select = True | ||
| 56 | + else: | ||
| 57 | + for bone in bones: | ||
| 58 | + bpy.context.object.pose.bones[bone].bone.select = True | ||
| 59 | + | ||
| 60 | +def deselect_bones(bones = None): | ||
| 61 | + if (isinstance(bones, int)): | ||
| 62 | + bpy.context.object.pose.bones[bones].bone.select = False | ||
| 63 | + else: | ||
| 64 | + for bone in bones: | ||
| 65 | + bpy.context.object.pose.bones[bone].bone.select = False | ||
| 66 | + | ||
| 50 | # Função responsável por selecionar as pose-libs e setar os frames | 67 | # Função responsável por selecionar as pose-libs e setar os frames |
| 51 | def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True): | 68 | def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True): |
| 52 | bpy.ops.object.mode_set(mode = 'OBJECT') | 69 | bpy.ops.object.mode_set(mode = 'OBJECT') |
| 53 | bpy.ops.object.select_all(action="DESELECT") | 70 | bpy.ops.object.select_all(action="DESELECT") |
| 54 | bpy.ops.object.mode_set(mode = 'POSE') | 71 | bpy.ops.object.mode_set(mode = 'POSE') |
| 55 | - | 72 | + |
| 56 | for x in range(len(positionFrames)): | 73 | for x in range(len(positionFrames)): |
| 57 | for l in range(len(actions)): | 74 | for l in range(len(actions)): |
| 58 | action = actions[l] | 75 | action = actions[l] |
| @@ -63,20 +80,20 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) | @@ -63,20 +80,20 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) | ||
| 63 | validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name | 80 | validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name |
| 64 | validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name | 81 | validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name |
| 65 | validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name | 82 | validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name |
| 66 | - | 83 | + |
| 67 | if (validHandConf or validPA or validO): | 84 | if (validHandConf or validPA or validO): |
| 68 | keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO) | 85 | keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO) |
| 69 | keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) | 86 | keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) |
| 70 | 87 | ||
| 71 | -def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): | 88 | +def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): |
| 72 | bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) | 89 | bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) |
| 73 | keyframe_id = bone.name + "_" + path | 90 | keyframe_id = bone.name + "_" + path |
| 74 | last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 | 91 | last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 |
| 75 | last_keyframe_dict[keyframe_id] = positionFrame | 92 | last_keyframe_dict[keyframe_id] = positionFrame |
| 76 | - | 93 | + |
| 77 | if (rotationFlag and path == "rotation_quaternion"): | 94 | if (rotationFlag and path == "rotation_quaternion"): |
| 78 | checkRotation(bone, positionFrame, last_keyframe) | 95 | checkRotation(bone, positionFrame, last_keyframe) |
| 79 | - | 96 | + |
| 80 | if (collisionFlag): | 97 | if (collisionFlag): |
| 81 | checkCollision(bone, path, positionFrame, last_keyframe) | 98 | checkCollision(bone, path, positionFrame, last_keyframe) |
| 82 | 99 | ||
| @@ -95,9 +112,9 @@ def checkRotation(bone, positionFrame, last_keyframe): | @@ -95,9 +112,9 @@ def checkRotation(bone, positionFrame, last_keyframe): | ||
| 95 | boneRQ = bone.rotation_quaternion.to_euler() | 112 | boneRQ = bone.rotation_quaternion.to_euler() |
| 96 | scene.frame_set(frame_current) | 113 | scene.frame_set(frame_current) |
| 97 | isRightHand = ".R" in bone.name | 114 | isRightHand = ".R" in bone.name |
| 98 | - resetBnMaoPosition(isRightHand) | 115 | + resetBnMaoPosition(isRightHand) |
| 99 | valid_rotation = validate_rotation(bone, positionFrame, last_keyframe) | 116 | valid_rotation = validate_rotation(bone, positionFrame, last_keyframe) |
| 100 | - | 117 | + |
| 101 | if (not valid_rotation): | 118 | if (not valid_rotation): |
| 102 | new_rotation = boneRQ.to_quaternion() * (-1) | 119 | new_rotation = boneRQ.to_quaternion() * (-1) |
| 103 | bone.rotation_quaternion = new_rotation | 120 | bone.rotation_quaternion = new_rotation |
| @@ -106,7 +123,7 @@ def checkRotation(bone, positionFrame, last_keyframe): | @@ -106,7 +123,7 @@ def checkRotation(bone, positionFrame, last_keyframe): | ||
| 106 | def checkCollision(bone, path, positionFrame, last_keyframe): | 123 | def checkCollision(bone, path, positionFrame, last_keyframe): |
| 107 | if (last_keyframe == positionFrame): | 124 | if (last_keyframe == positionFrame): |
| 108 | return | 125 | return |
| 109 | - | 126 | + |
| 110 | isRightHand = ".R" in bone.name | 127 | isRightHand = ".R" in bone.name |
| 111 | resetIKPosition(isRightHand) | 128 | resetIKPosition(isRightHand) |
| 112 | handCollisionFrame = check_hand_collision(last_keyframe, positionFrame) | 129 | handCollisionFrame = check_hand_collision(last_keyframe, positionFrame) |
| @@ -114,7 +131,7 @@ def checkCollision(bone, path, positionFrame, last_keyframe): | @@ -114,7 +131,7 @@ def checkCollision(bone, path, positionFrame, last_keyframe): | ||
| 114 | if (handCollisionFrame != -1): | 131 | if (handCollisionFrame != -1): |
| 115 | handle_collision(bone, path, positionFrame, handCollisionFrame) | 132 | handle_collision(bone, path, positionFrame, handCollisionFrame) |
| 116 | return | 133 | return |
| 117 | - | 134 | + |
| 118 | bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame) | 135 | bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame) |
| 119 | if (bodyCollisionFrame != -1): | 136 | if (bodyCollisionFrame != -1): |
| 120 | handle_collision(bone, path, positionFrame, bodyCollisionFrame) | 137 | handle_collision(bone, path, positionFrame, bodyCollisionFrame) |
| @@ -124,7 +141,7 @@ def handle_collision(bone, path, positionFrame, collisionFrame, rollbackFrames = | @@ -124,7 +141,7 @@ def handle_collision(bone, path, positionFrame, collisionFrame, rollbackFrames = | ||
| 124 | scene = bpy.context.scene | 141 | scene = bpy.context.scene |
| 125 | frame_current = scene.frame_current | 142 | frame_current = scene.frame_current |
| 126 | scene.frame_set(collisionFrame - rollbackFrames) | 143 | scene.frame_set(collisionFrame - rollbackFrames) |
| 127 | - bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) | 144 | + bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) |
| 128 | bpy.context.scene.frame_set(frame_current) | 145 | bpy.context.scene.frame_set(frame_current) |
| 129 | 146 | ||
| 130 | def check_hand_collision(initFrame, endFrame): | 147 | def check_hand_collision(initFrame, endFrame): |
| @@ -133,7 +150,7 @@ def check_hand_collision(initFrame, endFrame): | @@ -133,7 +150,7 @@ def check_hand_collision(initFrame, endFrame): | ||
| 133 | def check_collision(objName, otherObjName, initFrame, endFrame): | 150 | def check_collision(objName, otherObjName, initFrame, endFrame): |
| 134 | scene = bpy.context.scene | 151 | scene = bpy.context.scene |
| 135 | frame_current = scene.frame_current | 152 | frame_current = scene.frame_current |
| 136 | - startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) | 153 | + startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) |
| 137 | collisionFrame = -1 | 154 | collisionFrame = -1 |
| 138 | for i in range(startFrame, endFrame + 1, 1): | 155 | for i in range(startFrame, endFrame + 1, 1): |
| 139 | scene.frame_set(i) | 156 | scene.frame_set(i) |
| @@ -153,24 +170,23 @@ def check_body_collision(isRightHand, initFrame, endFrame): | @@ -153,24 +170,23 @@ def check_body_collision(isRightHand, initFrame, endFrame): | ||
| 153 | return result | 170 | return result |
| 154 | 171 | ||
| 155 | # Função que limpa todos os keyframes e define a quantidade de frames | 172 | # Função que limpa todos os keyframes e define a quantidade de frames |
| 156 | -def erase_all_keyframes(): | 173 | +def limpar_keyframes(): |
| 174 | + bpy.context.active_object.animation_data_clear() | ||
| 157 | for i in bpy.data.objects: | 175 | for i in bpy.data.objects: |
| 158 | i.animation_data_clear() | 176 | i.animation_data_clear() |
| 159 | - bpy.context.scene.frame_start = 1 | ||
| 160 | - bpy.context.scene.frame_current = bpy.context.scene.frame_start | ||
| 161 | - bpy.context.scene.frame_end = bpy.context.scene.frame_start | ||
| 162 | 177 | ||
| 163 | # Função que define as configurações de saida | 178 | # Função que define as configurações de saida |
| 164 | -def outconf(): | ||
| 165 | - erase_all_keyframes() | 179 | +def configure_output(): |
| 180 | + limpar_keyframes() | ||
| 181 | + bpy.context.scene.frame_start = 0 | ||
| 182 | + bpy.context.scene.frame_current = bpy.context.scene.frame_start | ||
| 183 | + bpy.context.scene.frame_end = bpy.context.scene.frame_start | ||
| 166 | bpy.context.scene.render.resolution_x = 640 | 184 | bpy.context.scene.render.resolution_x = 640 |
| 167 | bpy.context.scene.render.resolution_y = 480 | 185 | bpy.context.scene.render.resolution_y = 480 |
| 168 | bpy.context.scene.render.resolution_percentage = 100 | 186 | bpy.context.scene.render.resolution_percentage = 100 |
| 169 | bpy.context.scene.render.image_settings.file_format = 'H264' | 187 | bpy.context.scene.render.image_settings.file_format = 'H264' |
| 170 | bpy.context.scene.render.ffmpeg.format = 'MPEG4' | 188 | bpy.context.scene.render.ffmpeg.format = 'MPEG4' |
| 171 | bpy.context.scene.render.ffmpeg.codec = 'H264' | 189 | bpy.context.scene.render.ffmpeg.codec = 'H264' |
| 172 | - # bpy.context.scene.render.filepath = '/tmp/' | ||
| 173 | - | ||
| 174 | # Otimização da renderização | 190 | # Otimização da renderização |
| 175 | bpy.context.scene.render.use_shadows = False | 191 | bpy.context.scene.render.use_shadows = False |
| 176 | bpy.context.scene.render.use_raytrace = False | 192 | bpy.context.scene.render.use_raytrace = False |
| @@ -180,21 +196,16 @@ def outconf(): | @@ -180,21 +196,16 @@ def outconf(): | ||
| 180 | bpy.context.scene.render.tile_x = 320 | 196 | bpy.context.scene.render.tile_x = 320 |
| 181 | bpy.context.scene.render.tile_y = 240 | 197 | bpy.context.scene.render.tile_y = 240 |
| 182 | 198 | ||
| 183 | -def render_sign(userId, signName, beginFrame, endFrame): | ||
| 184 | - from sys import argv, path | ||
| 185 | - from os.path import abspath, dirname | ||
| 186 | - from pyutil import log, file_rename | ||
| 187 | - getcwd = dirname(abspath(__file__)) | ||
| 188 | - bpy.context.scene.render.filepath = getcwd + "/users/"+ str(userId)+ "/"+ signName + "_" | ||
| 189 | - bpy.context.scene.frame_start = beginFrame | ||
| 190 | - bpy.context.scene.frame_end = endFrame | ||
| 191 | - outFilename = ("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end)) | ||
| 192 | - log("All frames: %i" % (endFrame)) | 199 | +def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end): |
| 200 | + getcwd = os.path.dirname(os.path.abspath(__file__)) | ||
| 201 | + bpy.context.scene.render.filepath = getcwd + "/users/" + str(user_id) + "/"+ nome_sinal + "_" | ||
| 202 | + bpy.context.scene.frame_end = frame_final | ||
| 203 | + pyutil.log("Gerando Video... Frames: %i" % (frame_final)) | ||
| 193 | bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "") | 204 | bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "") |
| 194 | - file_rename(outFilename) | 205 | + pyutil.file_rename("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end)) |
| 195 | bpy.ops.wm.quit_blender() | 206 | bpy.ops.wm.quit_blender() |
| 196 | 207 | ||
| 197 | -# Função que recupera o frame final do movimento | 208 | +# descontinuada: get_endFrame |
| 198 | def get_endFrame(json_input, hands_frames_retilineo): | 209 | def get_endFrame(json_input, hands_frames_retilineo): |
| 199 | endsFrame = [18] | 210 | endsFrame = [18] |
| 200 | if(json_input["rightHand"] != []): | 211 | if(json_input["rightHand"] != []): |
| @@ -217,19 +228,19 @@ def get_endFrame(json_input, hands_frames_retilineo): | @@ -217,19 +228,19 @@ def get_endFrame(json_input, hands_frames_retilineo): | ||
| 217 | def validate_rotation(bone, endFrame, startFrame = 0): | 228 | def validate_rotation(bone, endFrame, startFrame = 0): |
| 218 | if (endFrame - startFrame == 1): | 229 | if (endFrame - startFrame == 1): |
| 219 | return True | 230 | return True |
| 220 | - | 231 | + |
| 221 | rotFrames = [[]] | 232 | rotFrames = [[]] |
| 222 | scene = bpy.context.scene | 233 | scene = bpy.context.scene |
| 223 | frame_current = scene.frame_current | 234 | frame_current = scene.frame_current |
| 224 | - | 235 | + |
| 225 | for i in range(startFrame+1, endFrame+1, 1): | 236 | for i in range(startFrame+1, endFrame+1, 1): |
| 226 | scene.frame_set(i) | 237 | scene.frame_set(i) |
| 227 | rotFrames[-1] = bone.rotation_quaternion.to_euler() | 238 | rotFrames[-1] = bone.rotation_quaternion.to_euler() |
| 228 | rotFrames.append([]) | 239 | rotFrames.append([]) |
| 229 | - | 240 | + |
| 230 | rotFrames.remove([]) | 241 | rotFrames.remove([]) |
| 231 | scene.frame_set(frame_current) | 242 | scene.frame_set(frame_current) |
| 232 | - | 243 | + |
| 233 | for k in range(1, len(rotFrames), 1): | 244 | for k in range(1, len(rotFrames), 1): |
| 234 | for i in range(0, 3, 1): | 245 | for i in range(0, 3, 1): |
| 235 | if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/2: | 246 | if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi/2: |
| @@ -241,6 +252,6 @@ def apply_rotation(bone, axis, currentFrame, endFrame, degree): | @@ -241,6 +252,6 @@ def apply_rotation(bone, axis, currentFrame, endFrame, degree): | ||
| 241 | new_rotation = bone.rotation_quaternion.to_euler() | 252 | new_rotation = bone.rotation_quaternion.to_euler() |
| 242 | new_rotation.rotate_axis(axis, math.radians(degree)) | 253 | new_rotation.rotate_axis(axis, math.radians(degree)) |
| 243 | new_rotation = new_rotation.to_quaternion() | 254 | new_rotation = new_rotation.to_quaternion() |
| 244 | - | 255 | + |
| 245 | bone.rotation_quaternion = new_rotation | 256 | bone.rotation_quaternion = new_rotation |
| 246 | keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True) | 257 | keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True) |
| 247 | \ No newline at end of file | 258 | \ No newline at end of file |