util.py 5.76 KB
# -*- coding: UTF-8 -*-

import bpy
import math

armature = bpy.context.scene.objects.get('Armature.001')

# Vetor com indices de cada bone do lado direito
rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66]

# Vetor com indices de cada bone do lado esquerdo
leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82]

# Vetor com indices de cada bone da face
faceBonesConf = [15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47]

# Vetor com indices de todos os bones
allBones = list(range(len(armature.pose.bones)))

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

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

# Movimento coçar - Índices de poses
cocar_mao_aberta_index = 56
cocar_mao_fechada_index = 24
cocar_orientation_index = 20

# 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))):
                keyframe_insert(armature.pose.bones[bones[i]], 'location', positionFrames[x])
                keyframe_insert(armature.pose.bones[bones[i]], 'rotation_quaternion', positionFrames[x])

def keyframe_insert(bone, path, positionFrame):
    bone.keyframe_insert(data_path = path, index = -1, frame = positionFrame)
    # collision

# Função que limpa todos os keyframes e define a quantidade de frames
def erase_all_keyframes():
    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()
    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
    bpy.context.scene.render.use_envmaps = False
    bpy.context.scene.render.use_motion_blur = False
    bpy.context.scene.render.use_shadows = False
    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))
    bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
    file_rename(outFilename)
    bpy.ops.wm.quit_blender()

# Função que recupera o frame final do movimento
def get_endFrame(json_input, hands_frames_retilineo):
    endsFrame = [18]
    if(json_input["rightHand"] != []):
        if(json_input["rightHand"][0] == "circular"):
            # Sugestao: json_input["rightHand"][4] eh o número de voltas/repeticoes? colocar numa variavel
            endsFrame.append(int(json_input["rightHand"][4]*8*5+18))
        elif(json_input["rightHand"][0] == "semicircular"):
            endsFrame.append(int(json_input["rightHand"][4]*5*5+18))
        elif(json_input["rightHand"][0] == "retilineo"):
            endsFrame.append(max(hands_frames_retilineo))
    if(json_input["leftHand"] != []):
        if(json_input["leftHand"][0] == "circular"):
            endsFrame.append(int(json_input["leftHand"][4]*8*5+18))
        elif(json_input["leftHand"][0] == "semicircular"):
            endsFrame.append(int(json_input["rightHand"][4]*5*5+18))
        elif(json_input["rightHand"][0] == "retilineo"):
            endsFrame.append(max(hands_frames_retilineo))
    return(max(endsFrame))

def validate_rotation(bone, endFrame):
    rotFrames = [[]]
    scene = bpy.context.scene
    frame_current = bpy.context.scene.frame_current
    
    for i in range(0, 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, endFrame + 1, 1):
            for i in range(0, 3, 1):
                    if (math.fabs(rotFrames[k][i] - rotFrames[k-1][i])) > math.pi :
                        return False
    return True

# Axis: "X", "Y" e "Z"
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)
    
    valid_rotation = validate_rotation(bone, endFrame)
    if (not valid_rotation):
        new_rotation *= (-1)
        bone.rotation_quaternion = new_rotation
        keyframe_insert(bone, 'rotation_quaternion', currentFrame)