From 8425c440950ffd24937356e04b947a1ea0bb4830 Mon Sep 17 00:00:00 2001 From: André Araújo Date: Sat, 8 Aug 2015 05:04:03 -0300 Subject: [PATCH] Altera código para formato JSON mais recente --- Makefile | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- controller.py | 23 ++++++++++++----------- libras.py | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------ moves.py | 27 ++++++++++++++++----------- param.json | 6 ++++-- util.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++------------------------------------ 6 files changed, 348 insertions(+), 113 deletions(-) diff --git a/Makefile b/Makefile index cefc357..72ced8b 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,136 @@ +JSON_ALL = \ +'{ \ + "userId": "lavid", \ + "sinal": "Modelo JSON", \ + "interpolacao": "lento|normal|rapido", \ + "movimentos": [ \ + { \ + "facial": { \ + "expressao": 0..21, \ + "velocidade": "lento|normal|rapido" \ + }, \ + "mao_esquerda": { \ + "circular": { \ + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ + "raio": "pequeno|medio|grande", \ + "velocidade": "lento|normal|rapido", \ + "lado_oposto": true|false, \ + "sentido_inverso": true|false, \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "semicircular": { \ + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ + "raio": "pequeno|medio|grande", \ + "lado_oposto": true|false, \ + "sentido_inverso": true|false, \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "contato": { \ + "alisar": { \ + "movimento_orientacao": "perpendicular|paralelo|diagonal-direita|diagonal-esquerda", \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "cocar": { \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "tocar": { \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "riscar": { \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + } \ + }, \ + "espiral": { \ + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ + "raio": "pequeno|medio|grande", \ + "lado_oposto": true|false, \ + "sentido_inverso": true|false, \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "helicoidal": { \ + "plano": "frente-esquerda|frente-cima|esquerda-cima", \ + "raio": "pequeno|medio|grande", \ + "lado_oposto": true|false, \ + "sentido_inverso": true|false, \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "pontual": { \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "retilineo": { \ + "velocidade": "lento|normal|rapido", \ + "articulacao_inicial": 0..124, \ + "articulacao_final": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + }, \ + "senoidal": { \ + "direcao": "frente|esquerda|cima", \ + "direcao_oposta": true|false, \ + "eixo_fixo": "frente-tras|esquerda-direita|cima-baixo", \ + "comprimento_onda": "pequeno|medio|grande", \ + "articulacao": 0..124, \ + "configuracao": 0..60, \ + "orientacao": 0..142 \ + } \ + }, \ + "mao_direita": { \ + } \ + } \ + ] \ +}' + +JSON = \ +'{ \ + "userId": "lavid", \ + "sinal": "Modelo JSON 2", \ + "ex_interpolacao": "lento|normal|rapido", \ + "interpolacao": "normal", \ + "movimentos": [ \ + { \ + "facial": { \ + "expressao": 21, \ + "velocidade": "lento|normal|rapido" \ + }, \ + "mao_esquerda": { \ + "circular": { \ + "plano": "esquerda-cima", \ + "raio": "pequeno", \ + "velocidade": "lento", \ + "lado_oposto": false, \ + "sentido_inverso": false, \ + "articulacao": 124, \ + "configuracao": 129, \ + "orientacao": 142 \ + } \ + }, \ + "mao_direita": { \ + } \ + } \ + ] \ +}' + BLEND = avatar_cartoon_v2.74.blend CONTROLLER = controller.py MAIN = libras.py -# Circular: ['circular', x, x, Raio=1, Voltas=3 CfM=0, PAr=80, Ori=0] -JSON = '{"userId": 4, "rightHand": ["circular", "plano", "horario", 1, 3, 0, 80, 0], "leftHand":[], "facialExp": [1], "signName": "teste circular"}' -#JSON = '{"userId": 4, "rightHand": ["pontual", 55, 81, 21], "leftHand":[], "facialExp": [], "signName": "teste pontual"}' -#JSON = '{"userId": 4, "rightHand": ["pontual", 0, 80, 1], "leftHand":[], "facialExp": [1], "signName": "teste facial 1"}' -#JSON = '{"userId": 4, "rightHand": ["pontual", 0, 80, 2], "leftHand":[], "facialExp": [21], "signName": "teste facial 2"}' BLENDER = blender CACHE += "./__pycache__" CACHE += "./users" diff --git a/controller.py b/controller.py index b5e5432..3b837a0 100644 --- a/controller.py +++ b/controller.py @@ -1,22 +1,23 @@ # -*- coding: UTF-8 -*- -from subprocess import call -from sys import argv -from os.path import abspath, dirname, join +import subprocess +import sys +import os -getcwd = dirname(abspath(__file__)) +getcwd = os.path.dirname(os.path.abspath(__file__)) -from pyutil import printStackTrace +import pyutil + +blend_path = os.path.join(getcwd, "avatar_cartoon_v2.74.blend") +main_path = os.path.join(getcwd, "libras.py") -blend_path = join(getcwd, "avatar_cartoon_v2.74.blend") -main_path = join(getcwd, "libras.py") result = 0 try: - # Caso seja necessário gravar logs do blender utilizar a linha de código abaixo - # result = call(['blender', '-b', blend_path, '-P', main_path, '--', argv[1]], stdout = open('bpy.log', 'w')) - result = call(['blender', '-b', blend_path, '-P', main_path, '--', argv[1]]) + # para gravar logs do blender, usar codigo abaixo + # result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]], stdout = open('bpy.log', 'w')) + result = subprocess.call(['blender', '-b', blend_path, '-P', main_path, '--', sys.argv[1]]) except: - result = printStackTrace(__file__) + result = pyutil.printStackTrace(__file__) exit(result) diff --git a/libras.py b/libras.py index 634a00a..18807cc 100644 --- a/libras.py +++ b/libras.py @@ -5,71 +5,111 @@ import bpy # importa modulos do Python import json -from sys import argv, path -from os.path import abspath, dirname +import sys +import os -# define o caminho absoluto do diretório deste arquivo -getcwd = dirname(abspath(__file__)) +# define o caminho absoluto do diretorio deste arquivo +getcwd = os.path.dirname(os.path.abspath(__file__)) # insere o caminho do diretorio atual no path (permite o acesso aos modulos locais) -path.insert(0, getcwd) +sys.path.insert(0, getcwd) # importa modulos locais -import util, moves -from pyutil import printStackTrace - -# tenta decodificar o argumento JSON recebido -try: - json_input = json.loads(argv[6]) -except Exception: - printStackTrace(__file__) - exit(1) - -# ajusta as configurações de renderização -util.outconf() - -# Cria uma Action -act = bpy.context.scene.animation_data_create() - -# Função responsável por setar pose padrão -def poseDefault(positionFrames, collisionFlag = False): +import util +import moves +import pyutil + +# intervalos de interpolacao dos keyframes +interpolation = {'inicial': 20, 'lento': 5, 'normal': 10, 'rapido': 15, 'final': 20} + +def insert_keyframe_pose_default(current_frame = 0, frame_jump = 0, pose_bones = bpy.context.object.pose.bones, types_keyframe = ['location', 'rotation_quaternion']): + for obj in (pose_bones): + obj.bone.select = True + for type_keyframe in types_keyframe: + obj.keyframe_insert(index = -1, frame = current_frame, group = obj.name, data_path = type_keyframe) + obj.bone.select = False + return current_frame + frame_jump + +def pose_default(current_frame = 0, frame_jump = 0, actions = bpy.data.actions): + result = 0 + for action in actions: + if (action.use_fake_user): + bpy.context.object.pose_library = action + bpy.ops.poselib.apply_pose(pose_index = 0) + result = insert_keyframe_pose_default(current_frame, frame_jump) + return result + +def decode_circular_semicircular(js_movement, current_frame, frame_jump, is_right_hand, is_semicircular): + # const + obj_raio = {'pequeno': 0.5, 'normal': 1.0, 'grande': 1.5} + obj_periodo = {'lento': 55, 'normal': 45, 'rapido': 35} + # decodificar valores + raio = obj_raio[js_movement['raio']] + periodo = obj_periodo[js_movement['velocidade']] + # diminuir a velocidade + if (js_movement['velocidade'] == 'lento'): + periodo += 10 + # aumentar a velocidade + elif (js_movement['velocidade'] == 'rapido'): + periodo -= 10 + # definir eixos do movimento + if (js_movement['plano'] == 'frente-esquerda'): + x, y = 2, 0 + elif (js_movement['plano'] == 'frente-cima'): + x, y = 2, 1 + else: + x, y = 0, 1 + # mao usada (direita/esquerda) + if (is_right_hand): + ik = bpy.context.object.pose.bones[1] + else: + ik = bpy.context.object.pose.bones[0] + current_frame = insert_keyframe_pose_default(current_frame, frame_jump, [ik], ['location']) + current_frame = moves.circular(ik, current_frame + frame_jump, raio, periodo, x, y, js_movement['lado_oposto'], js_movement['sentido_inverso'], is_semicircular) + return current_frame + +def decode_hand_mov(current_frame, frame_jump, js_mao, is_right_hand): + if (js_mao == {}): + return + movement_name = next(iter(js_mao.keys())) + print("Movimento: " + movement_name) + if (movement_name == 'circular'): + current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, False) + elif (movement_name == 'semicircular'): + current_frame = decode_circular_semicircular(js_mao[movement_name], current_frame, frame_jump, is_right_hand, True) + return current_frame + frame_jump + +# Funcao responsavel por setar pose padrao +def poseDefault(json_input, positionFrames, collisionFlag = False): handDefaultParam = [0, 0, 0] util.setPose(util.right_hand_actions, handDefaultParam, positionFrames, util.rightBonesConf, collisionFlag) if(json_input["leftHand"] != []): util.setPose(util.left_hand_actions, handDefaultParam, positionFrames, util.leftBonesConf, collisionFlag) #setFaceConfiguration([0], positionFrames, util.faceBonesConf) -# Função responsável por setar as configurações das mãos +# Funcao responsavel por setar as configuracoes das maos def setHandConfiguration(actions, handParam, positionFrames, bones): util.setPose(actions, handParam, positionFrames, bones) -# Função responsável por setar a configuração da face +# Funcao responsavel por setar a configuracao da face def setFaceConfiguration(handParam, positionFrames, bones): util.setPose(util.facial_expression_action, handParam, positionFrames, bones) -# Sugestao: Alguma forma de uniformizar o calculo do endFrame (atualizado aqui e no movimento circular) -initialFrame, endFrame = 15, util.get_endFrame(json_input, util.hands_frames_retilineo) - -#------------------ Configurações------------------------------ - -#Função que inicia a configuração de ambas as mãos -def configureHands(): - # Array com valores dos campos que serão passados pelo JSON +#Funcao que inicia a configuracao de ambas as maos +def configureHands(endFrame): + # Array com valores dos campos que serao passados pelo JSON hands = ["rightHand", "leftHand"] iks = ["ik_FK.R", "ik_FK.L"] bones_ = [util.rightBonesConf, util.leftBonesConf] # Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo actions = [util.right_hand_actions, util.left_hand_actions] - global endFrame for i in range(len(hands)): if(json_input[hands[i]] != []): move = json_input[hands[i]][0] pose = util.armature.pose.bones[iks[i]] handParam = json_input[hands[i]][-3:] - if(move in ["pontual", "circular", "semicircular", "retilineo", "senoidal"]): setHandConfiguration(actions[i], handParam, util.hands_default_frames, bones_[i]) - if(move in ["circular", "semicircular"]): orientation, direction, radius, laps = json_input[hands[i]][1:5] #endFrame = moves.circular_or_semiCircular(pose, orientation, direction, radius, laps, 5) @@ -84,20 +124,71 @@ def configureHands(): elif(move == "contato"): endFrame = moves.contato(actions[i], json_input[hands[i]], bones_[i], pose) -# Função que inicia a configuração da face -def configureFace(): - global endFrame - if(json_input["facialExp"] != []): - setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) +# Funcao que inicia a configuracao da face +def setFacialExpr(a, b): + pass + #if(json_input["facialExp"] != []): + # setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) def main(): - poseDefault([1]) - configureHands() - configureFace() - poseDefault([endFrame + 15]) - # Default Pose - print("Total frames: %.3i" % (endFrame)) - util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25) + util.configure_output() + bpy.context.scene.animation_data_create() + + try: + js_input = json.loads(sys.argv[6]) + js_movimentos = js_input['movimentos'] + frame_jump = interpolation[js_input['interpolacao']] + + endFrame = pose_default(0) + facial_frame = 0 + mao_esquerda_frame = 0 + mao_direita_frame = 0 + + # setar pose padrao inicial em todos os bones ('location' e 'rotation_quaternion') + endFrame += pose_default(interpolation['inicial']) + + for i in range(0, len(js_movimentos)): + + js_facial = js_movimentos[i]['facial'] + + if (js_facial != {}): + setFacialExpr(js_facial['expressao'], js_facial['velocidade']) + else: + pyutil.log(" Expressao Facial %d" % (i)) + + js_mao_esquerda = js_movimentos[i]['mao_esquerda'] + if (js_mao_esquerda != {}): + mao_esquerda_frame += decode_hand_mov(mao_esquerda_frame, frame_jump, js_mao_esquerda, False) + else: + pyutil.log(" mov %d Mao esquerda" % (i)) + + js_mao_direita = js_movimentos[i]['mao_direita'] + if (js_mao_direita != {}): + mao_direita_frame += decode_hand_mov(mao_direita_frame, frame_jump, js_mao_direita, True) + else: + pyutil.log(" mov %d Mao direita" % (i)) + + endFrame = max(facial_frame, mao_esquerda_frame, mao_direita_frame) + endFrame += frame_jump + + # setar pose padrao final em todos os bones (location e rotation) + #endFrame += pose_default(endFrame + interpolation['final']) + endFrame = insert_keyframe_pose_default(endFrame, frame_jump) + endFrame += interpolation['final'] + + # Sugestao: Alguma forma de uniformizar o calculo do endFrame (atualizado aqui e no movimento circular) + #initialFrame = 15 + #endFrame = util.get_endFrame(js_input, util.hands_frames_retilineo) + #poseDefault([1]) + #configureHands(endFrame) + #configureFace(endFrame) + #poseDefault(js_input, [endFrame + 15]) + + util.render_sign(js_input["userId"], js_input["sinal"], endFrame) + + except: + pyutil.printStackTrace(__file__) + raise if __name__ == "__main__": main() diff --git a/moves.py b/moves.py index 915f126..ad29072 100644 --- a/moves.py +++ b/moves.py @@ -159,14 +159,14 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi # raio: "grande" raio = 1.5, velocidade: "normal" periodo = 55 # raio: "grande" raio = 1.5, velocidade: "lento" periodo = 65 # @param obj: (objeto) bone, mesh, e.g. -# @param itFrame: (int) posicao onde o primeiro keyframe vai ser inserido +# @param frame_atual: (int) posicao onde o primeiro keyframe vai ser inserido # @param raio: (int) raio da circunferencia # @param periodo: (int) quantidade de keyframes necessarios para completar uma volta completa # @param x: (int) in [0,1,2] define qual eixo vai variar no seno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) # @param y: (int) in [0,1,2] define qual eixo vai variar no cosseno (0 = eixo X, 1 = eixo Y, 2 = eixo Z) -# @param ladoOposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar) -# @param inverterDirecao (bool) inverte o sentido do movimento (horario para anti-horario) -def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inverterDirecao = False): +# @param usar_lado_oposto: (bool) inverte o lado da primeira posicao (pode ser util em alguns casos para espelhar) +# @param usar_sentido_oposto (bool) inverte o sentido do movimento (horario para anti-horario) +def circular(obj, frame_atual, raio, periodo, x = 0, y = 1, usar_lado_oposto = False, usar_sentido_oposto = False, meia_volta = False): # limita inferiormente if (periodo < 16): periodo = 16 @@ -174,7 +174,7 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve elif (periodo > 360): periodo = 360 # muda lado inicial - if (ladoOposto): + if (usar_lado_oposto): k = round(periodo / 2) else: k = 0 @@ -182,17 +182,22 @@ def circular(obj, itFrame, raio, periodo, x = 0, y = 1, ladoOposto = False, inve x %= 3 y %= 3 # inverte direcao do movimento - if (inverterDirecao): + if (usar_sentido_oposto): tmp = x x = y y = tmp # copia posicao inicial para transladar loc = [obj.location[0], obj.location[1], obj.location[2]] - for i in range(k, periodo + k): - # pequena otimizacao para reduzir a quantidade de keyframes - if (itFrame % 2 == 0): + # semi-circular + limite = periodo + k + if (meia_volta): + limite = round(limite / 2) + for i in range(k, limite + 1): + # reduz a quantidade de keyframes + if (frame_atual % 2 == 0): obj.location[x] = loc[x] + (raio * math.cos(i / periodo * (2 * math.pi))) obj.location[y] = loc[y] + (raio * math.sin(i / periodo * (2 * math.pi))) - util.keyframe_insert(obj, 'location', itFrame) - itFrame += 1 + util.keyframe_insert(obj, 'location', frame_atual) + frame_atual += 1 + util.keyframe_insert(obj, 'location', frame_atual) return periodo - 1 diff --git a/param.json b/param.json index 4deb7e0..e9d0219 100644 --- a/param.json +++ b/param.json @@ -13,6 +13,7 @@ "circular": { "plano": "frente-esquerda|frente-cima|esquerda-cima", "raio": "pequeno|medio|grande", + "velocidade": "lento|normal|rapido", "lado_oposto": false, "sentido_inverso": false, "articulacao": 124, @@ -22,6 +23,7 @@ "semicircular": { "plano": "frente-esquerda|frente-cima|esquerda-cima", "raio": "pequeno|medio|grande", + "velocidade": "lento|normal|rapido", "lado_oposto": false, "sentido_inverso": false, "articulacao": 124, @@ -82,8 +84,8 @@ "orientacao": 142 }, "retilineo": { - "articulacao_inicial_id": 124, - "articulacao_final_id": 124, + "articulacao_inicial": 124, + "articulacao_final": 124, "configuracao": 129, "orientacao": 142 }, diff --git a/util.py b/util.py index 524f468..93e18e2 100644 --- a/util.py +++ b/util.py @@ -2,6 +2,9 @@ import bpy import math +import pyutil +import os +import sys from bmesh_collision import bmesh_check_intersect_objects armature = bpy.context.scene.objects.get('Armature.001') @@ -47,12 +50,26 @@ left_hand_actions = [conf_esquerda_id, pa_esquerda_id, orient_esquerda_id] last_keyframe_dict = {} +def select_bones(bones = None): + if (isinstance(bones, int)): + bpy.context.object.pose.bones[bones].bone.select = True + else: + for bone in bones: + bpy.context.object.pose.bones[bone].bone.select = True + +def deselect_bones(bones = None): + if (isinstance(bones, int)): + bpy.context.object.pose.bones[bones].bone.select = False + else: + for bone in bones: + bpy.context.object.pose.bones[bone].bone.select = False + # Função responsável por selecionar as pose-libs e setar os frames def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True): bpy.ops.object.mode_set(mode = 'OBJECT') bpy.ops.object.select_all(action="DESELECT") bpy.ops.object.mode_set(mode = 'POSE') - + for x in range(len(positionFrames)): for l in range(len(actions)): action = actions[l] @@ -63,20 +80,20 @@ def setPose(actions, parametesConf, positionFrames, bones, collisionFlag = True) validHandConf = action in [conf_direita_id, conf_esquerda_id] and "BnDedo" in bone.name validPA = action in [pa_direita_id, pa_esquerda_id] and "ik_FK" in bone.name or "BnPolyV" in bone.name validO = action in [orient_direita_id, orient_esquerda_id] and "BnMao" in bone.name - + if (validHandConf or validPA or validO): keyframe_insert(bone, 'location', positionFrames[x], collisionFlag and validPA, validO) keyframe_insert(bone, 'rotation_quaternion', positionFrames[x], collisionFlag and validPA, validO) -def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): +def keyframe_insert(bone, path, positionFrame, collisionFlag = True, rotationFlag = False): bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) keyframe_id = bone.name + "_" + path last_keyframe = last_keyframe_dict[keyframe_id] if keyframe_id in last_keyframe_dict else 0 last_keyframe_dict[keyframe_id] = positionFrame - + if (rotationFlag and path == "rotation_quaternion"): checkRotation(bone, positionFrame, last_keyframe) - + if (collisionFlag): checkCollision(bone, path, positionFrame, last_keyframe) @@ -95,9 +112,9 @@ def checkRotation(bone, positionFrame, last_keyframe): boneRQ = bone.rotation_quaternion.to_euler() scene.frame_set(frame_current) isRightHand = ".R" in bone.name - resetBnMaoPosition(isRightHand) + resetBnMaoPosition(isRightHand) valid_rotation = validate_rotation(bone, positionFrame, last_keyframe) - + if (not valid_rotation): new_rotation = boneRQ.to_quaternion() * (-1) bone.rotation_quaternion = new_rotation @@ -106,7 +123,7 @@ def checkRotation(bone, positionFrame, last_keyframe): def checkCollision(bone, path, positionFrame, last_keyframe): if (last_keyframe == positionFrame): return - + isRightHand = ".R" in bone.name resetIKPosition(isRightHand) handCollisionFrame = check_hand_collision(last_keyframe, positionFrame) @@ -114,7 +131,7 @@ def checkCollision(bone, path, positionFrame, last_keyframe): if (handCollisionFrame != -1): handle_collision(bone, path, positionFrame, handCollisionFrame) return - + bodyCollisionFrame = check_body_collision(isRightHand, last_keyframe, positionFrame) if (bodyCollisionFrame != -1): handle_collision(bone, path, positionFrame, bodyCollisionFrame) @@ -124,7 +141,7 @@ def handle_collision(bone, path, positionFrame, collisionFrame, rollbackFrames = scene = bpy.context.scene frame_current = scene.frame_current scene.frame_set(collisionFrame - rollbackFrames) - bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) + bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame) bpy.context.scene.frame_set(frame_current) def check_hand_collision(initFrame, endFrame): @@ -133,7 +150,7 @@ def check_hand_collision(initFrame, endFrame): def check_collision(objName, otherObjName, initFrame, endFrame): scene = bpy.context.scene frame_current = scene.frame_current - startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) + startFrame = initFrame + int(math.fabs((endFrame - initFrame)/2)) collisionFrame = -1 for i in range(startFrame, endFrame + 1, 1): scene.frame_set(i) @@ -153,24 +170,23 @@ def check_body_collision(isRightHand, initFrame, endFrame): return result # Função que limpa todos os keyframes e define a quantidade de frames -def erase_all_keyframes(): +def limpar_keyframes(): + bpy.context.active_object.animation_data_clear() for i in bpy.data.objects: i.animation_data_clear() - bpy.context.scene.frame_start = 1 - bpy.context.scene.frame_current = bpy.context.scene.frame_start - bpy.context.scene.frame_end = bpy.context.scene.frame_start # Função que define as configurações de saida -def outconf(): - erase_all_keyframes() +def configure_output(): + limpar_keyframes() + bpy.context.scene.frame_start = 0 + bpy.context.scene.frame_current = bpy.context.scene.frame_start + bpy.context.scene.frame_end = bpy.context.scene.frame_start bpy.context.scene.render.resolution_x = 640 bpy.context.scene.render.resolution_y = 480 bpy.context.scene.render.resolution_percentage = 100 bpy.context.scene.render.image_settings.file_format = 'H264' bpy.context.scene.render.ffmpeg.format = 'MPEG4' bpy.context.scene.render.ffmpeg.codec = 'H264' - # bpy.context.scene.render.filepath = '/tmp/' - # Otimização da renderização bpy.context.scene.render.use_shadows = False bpy.context.scene.render.use_raytrace = False @@ -180,21 +196,16 @@ def outconf(): bpy.context.scene.render.tile_x = 320 bpy.context.scene.render.tile_y = 240 -def render_sign(userId, signName, beginFrame, endFrame): - from sys import argv, path - from os.path import abspath, dirname - from pyutil import log, file_rename - getcwd = dirname(abspath(__file__)) - bpy.context.scene.render.filepath = getcwd + "/users/"+ str(userId)+ "/"+ signName + "_" - bpy.context.scene.frame_start = beginFrame - bpy.context.scene.frame_end = endFrame - outFilename = ("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end)) - log("All frames: %i" % (endFrame)) +def render_sign(user_id, nome_sinal = "sinal", frame_final = bpy.context.scene.frame_end): + getcwd = os.path.dirname(os.path.abspath(__file__)) + bpy.context.scene.render.filepath = getcwd + "/users/" + str(user_id) + "/"+ nome_sinal + "_" + bpy.context.scene.frame_end = frame_final + pyutil.log("Gerando Video... Frames: %i" % (frame_final)) bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "") - file_rename(outFilename) + pyutil.file_rename("%s%0.4i-%0.4i.mp4" % (bpy.context.scene.render.filepath, bpy.context.scene.frame_start, bpy.context.scene.frame_end)) bpy.ops.wm.quit_blender() -# Função que recupera o frame final do movimento +# descontinuada: get_endFrame def get_endFrame(json_input, hands_frames_retilineo): endsFrame = [18] if(json_input["rightHand"] != []): @@ -217,19 +228,19 @@ def get_endFrame(json_input, hands_frames_retilineo): def validate_rotation(bone, endFrame, startFrame = 0): if (endFrame - startFrame == 1): return True - + rotFrames = [[]] scene = bpy.context.scene frame_current = scene.frame_current - + for i in range(startFrame+1, endFrame+1, 1): scene.frame_set(i) rotFrames[-1] = bone.rotation_quaternion.to_euler() rotFrames.append([]) - + rotFrames.remove([]) scene.frame_set(frame_current) - + for k in range(1, len(rotFrames), 1): for i in range(0, 3, 1): 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): new_rotation = bone.rotation_quaternion.to_euler() new_rotation.rotate_axis(axis, math.radians(degree)) new_rotation = new_rotation.to_quaternion() - + bone.rotation_quaternion = new_rotation keyframe_insert(bone, 'rotation_quaternion', currentFrame, False, True) \ No newline at end of file -- libgit2 0.21.2