libras.py 4.96 KB
# -*- coding: UTF-8 -*-

# importa modulo do Blender
import bpy

# importa modulos do Python
import json
from sys import argv, path
from os.path import abspath, dirname

# define o caminho absoluto do diretório deste arquivo
getcwd = dirname(abspath(__file__))

# insere o caminho do diretorio atual no path (permite o acesso aos modulos locais)
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[5])
except Exception:
    printStackTrace(__file__)
    exit(1)

# ajusta as configurações de renderização
util.outconf()

# define a posição dos keyframes
hands_default_frames = [15, 18]

# define a posição dos keyframes
hands_frames_retilineo = [30, 33]

# Carrega o objeto presente no avatar
armature = bpy.context.scene.objects.get('Armature.001')

# Cria uma Action
act = bpy.context.scene.animation_data_create()

# Função responsável por selecionar as pose-libs e setar os frames
def setPose(actions, parametesConf, positionFrames, bones):
    bpy.ops.object.mode_set(mode = 'OBJECT')
    bpy.ops.object.select_all(action="DESELECT")
    bpy.ops.object.mode_set(mode = 'POSE')
    for l in range(len(actions)):
        armature.pose_library = bpy.data.actions[actions[l]]
        for x in range(len(positionFrames)):
            bpy.ops.poselib.apply_pose(pose_index = parametesConf[l])
            for i in range(0, (len(bones))):
                armature.pose.bones[bones[i]].keyframe_insert(data_path = 'location', index = -1, frame = positionFrames[x])
                armature.pose.bones[bones[i]].keyframe_insert(data_path = 'rotation_quaternion', index = -1, frame = positionFrames[x])

# Função responsável por setar pose padrão
def poseDefault(positionFrames, bones):
    setPose([0], [0], positionFrames, bones)

# Função responsável por setar as configurações das mãos
def setHandConfiguration(actions, handParam, positionFrames, bones):
    setPose(actions, handParam, positionFrames, bones)

# Função responsável por setar a configuração da face
def setFaceConfiguration(handParam, positionFrames, bones):    
    setPose([7], 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, 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
    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 = [[1, 3, 5], [2, 4, 6]]
    global endFrame
    for i in range(len(hands)):
        if(json_input[hands[i]] != []):
            move = json_input[hands[i]][0]
            pose = armature.pose.bones[iks[i]]
            handParam = json_input[hands[i]][-3:]
            
            if(move == "pontual"):
                setHandConfiguration(actions[i], handParam, hands_default_frames, bones_[i])
            else:
                setHandConfiguration(actions[i], handParam, hands_default_frames, bones_[i])
                
                if(move == "circular" or move == "semicircular"):
                    orientation, direction, radius, laps = json_input[hands[i]][1:5]
                    endFrame = moves.circular_or_semiCircular(pose, orientation, direction, radius, laps, 5)
                    setHandConfiguration(actions[i], handParam, [endFrame], bones_[i])
                elif(move == "retilineo"):
                    setHandConfiguration(actions[i], json_input[hands[i]][-6:-3], hands_default_frames, bones_[i])
                    setHandConfiguration(actions[i], handParam, hands_frames_retilineo, bones_[i])
                elif(move == "senoidal"):
                    orientation, direction, radius, laps = json_input[hands[i]][1:5]
                    endFrame = circular_or_semiCircular(pose, orientation, direction, radius, laps, 5)
                    setHandConfiguration(actions[i], handParam, [endFrame], bones_[i])
                elif(move == "contato"):
                    contact_type, orientation, repetition = json_input[hands[i]][1:4]
                    endFrame = moves.contato(pose, contact_type, orientation, repetition)
                    setHandConfiguration(actions[i], handParam, [endFrame], bones_[i])

# Função que inicia a configuração da face
def configureFace():
    global endFrame
    if(json_input["facialExp"] != []):
        # Set face
        setFaceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf)

configureHands()
configureFace()

poseDefault([1, endFrame + 15], util.allBones)

# Default Pose
print("Total frames: %.3i" % (endFrame))

util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25)