Commit ab51f390bdcf2d76115c52c1916c2175fb1878cc

Authored by gtaaas
2 parents 7c8f4648 4973c0eb
Exists in master

Realiza merge

Showing 4 changed files with 114 additions and 46 deletions   Show diff stats
Makefile 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +BLENDER = blender
  2 +DONE = [\33[30;32mOK\33[m]\n
  3 +FAIL = [\33[30;31mERRO\33[m]\n
  4 +MODULE = Wikilibras
  5 +CLEAR = @echo -n "\033c"
  6 +CACHE = __pycache__
  7 +SCRIPT = libras.py
  8 +AVATAR = avatar_Hozana_wikiLibras.blend
  9 +JSON = '{"userId": 4,"rightHand": ["circular", "perpendicular", "horario", 0.6, 1, 20, 4, 6], "leftHand":["pontual", 10, 3, 3], "facialExp": [6], "signName":"teste_circular"}'
  10 +
  11 +default: main
  12 +
  13 +main:
  14 + $(CLEAR)
  15 + @echo Executando...
  16 + @$(BLENDER) -b $(AVATAR) -P $(SCRIPT) $(JSON) && echo "$(DONE)" || { echo "$(FAIL)"; exit 1; }
  17 +
  18 +clean:
  19 + $(CLEAR)
  20 + @echo -n "Limpando..."
  21 + @rm -rf $(CACHE) > /dev/null 2>&1 && echo " $(DONE)" || { echo " $(FAIL)"; exit 1; }
... ...
libras.py
1 1 # -*- coding: UTF-8 -*-
2 2  
3   -# importa modulos do Python
4   -import sys
  3 +# importa modulos do Blender e Python
  4 +import bpy
  5 +import json
5 6 import os
6   -# insere o diretorio atual no path
7   -# permite que o código seja executado de qualquer diretório, possibilitando acesso aos modulos locais
  7 +import sys
  8 +
  9 +# insere o diretorio atual no path (permite o acesso aos modulos locais)
8 10 sys.path.append(os.getcwd())
9 11  
10   -# importa modulos nativos do Blender e Python
11   -import bpy
12   -import json
13 12 # importa modulos locais
14 13 import util
15 14 import moves
16 15  
17   -# verifica a quantidade de argumentos recebidos
18   -if (len(sys.argv) != 6):
19   - print ("WikiLibras: Invalid number of arguments")
20   - exit(1)
21   -
22 16 # tenta decodificar o argumento JSON recebido
23 17 try:
  18 + util.file_rename("./users/4/teste_circular_0001-0083.mp4")
24 19 json_input = json.loads(sys.argv[5])
25   -except (ValueError, KeyError, TypeError):
26   - print ("WikiLibras: JSON format error")
  20 +except Exception:
  21 + util.printStackTrace(__file__)
27 22 exit(1)
28 23  
29 24 # ajusta as configuraçẽs de renderização
... ... @@ -38,12 +33,12 @@ hands_frames_retilineo = [30,33]
38 33 armature = bpy.context.scene.objects.get('Armature.001')
39 34  
40 35 # Cria uma Action
41   -act = bpy.context.scene.animation_data_create()
  36 +act = bpy.context.scene.animation_data_create()
42 37  
43   -# Função responsável por selecionar as pose-libs e setar os frames
  38 +# Função responsável por selecionar as pose-libs e setar os frames
44 39 def setPose(actions, parametesConf, positionFrames, bones):
45 40 bpy.ops.object.mode_set(mode = 'OBJECT')
46   - bpy.ops.object.select_all(action="DESELECT")
  41 + bpy.ops.object.select_all(action="DESELECT")
47 42 bpy.ops.object.mode_set(mode = 'POSE')
48 43 for l in range(len(actions)):
49 44 armature.pose_library = bpy.data.actions[actions[l]]
... ... @@ -54,8 +49,8 @@ def setPose(actions, parametesConf, positionFrames, bones):
54 49 armature.pose.bones[bones[i]].keyframe_insert(data_path = 'rotation_quaternion', index = -1, frame = positionFrames[x])
55 50  
56 51 # Função responsável por setar pose padrão
57   -def poseDefault(positionFrames, bones):
58   - setPose([0], [0], positionFrames, bones)
  52 +def poseDefault(positionFrames, bones):
  53 + setPose([0], [0], positionFrames, bones)
59 54  
60 55 # Função responsável por setar as configuraçẽs das mãos
61 56 def generationConfigurations(actions, handParam, positionFrames, bones):
... ... @@ -72,11 +67,11 @@ initialFrame, endFrame = 15, util.get_endFrame(json_input,hands_frames_retilineo
72 67 #Função que inicia a configuração de ambas as mãos
73 68 def configureHands():
74 69 # Array com valores dos campos que serão passados pelo JSON
75   - hands = ["rightHand", "leftHand"]
  70 + hands = ["rightHand", "leftHand"]
76 71 iks = ['ik_FK.R', 'ik_FK.L']
77 72 bones_ = [util.rightBonesConf, util.leftBonesConf]
78 73 #Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo
79   - actions = [[1, 3, 5], [2, 4, 6]]
  74 + actions = [[1, 3, 5], [2, 4, 6]]
80 75 global endFrame
81 76 for i in range(len(hands)):
82 77 if(json_input[hands[i]] != []):
... ... @@ -93,19 +88,27 @@ def configureHands():
93 88 elif(move == "retilineo"):
94 89 generationConfigurations(actions[i], json_input[hands[i]][-6:-3], hands_default_frames, bones_[i])
95 90 generationConfigurations(actions[i], json_input[hands[i]][-3:],hands_frames_retilineo, bones_[i])
  91 +<<<<<<< HEAD
96 92  
97 93  
  94 +=======
  95 + elif(json_input[hands[i]][0] == "senoidal"):
  96 + orientation, direction, radius, laps = json_input[hands[i]][1:5]
  97 + endFrame = circular_or_semiCircular(pose, orientation, direction, radius, laps, 5)
  98 + generationConfigurations(actions[i], json_input[hands[i]][-3:], [endFrame], bones_[i])
  99 +
  100 +>>>>>>> 4973c0eb8bf544c810f4405a8974cf6e962d7bd4
98 101 # Função que inicia a configuração da face
99   -def configureFace():
  102 +def configureFace():
100 103 global endFrame
101 104 if(json_input["facialExp"] != []):
102 105 # Set face
103   - faceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf)
  106 + faceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf)
104 107  
105 108 # Default Pose
106 109 print(endFrame)
107   -poseDefault([1, endFrame+15], util.allBones)
  110 +poseDefault([1, endFrame + 15], util.allBones)
108 111 configureHands()
109 112 configureFace()
110 113  
111   -util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25)
112 114 \ No newline at end of file
  115 +util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25)
... ...
moves.py
1 1 # -*- coding: UTF-8 -*-
  2 +
2 3 import math
3 4  
4 5 def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensity = 5, initialFrame = 18, turn = None):
... ... @@ -7,7 +8,7 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi
7 8 if(direction == 'horario'):
8 9 endFrame = moves.locationCircular(center, radius, 1, 0, 2, pose, 0, laps, intensity, initialFrame,turn)
9 10 else:
10   - endFrame = moves.locationCircular(center, radius, 0, 1, 2, pose, 0, laps, intensity, initialFrame,turn)
  11 + endFrame = moves.locationCircular(center, radius, 0, 1, 2, pose, 0, laps, intensity, initialFrame,turn)
11 12 elif(orientation == 'paralelo'):
12 13 if(direction == 'horario'):
13 14 endFrame = moves.locationCircular(center, radius, 1, 2, 0, pose, 0, laps, intensity, initialFrame,turn)
... ... @@ -20,6 +21,11 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi
20 21 endFrame = moves.locationCircular(center, radius, 0, 2, 1, pose, 0, laps, intensity, initialFrame,turn)
21 22 return endFrame
22 23  
  24 +# center[3]: float vector (posição xyz centro)
  25 +# radius: float (distancia do centro)
  26 +# i_axis: int (indice do eixo i [0 | 1 | 2])
  27 +# j_axis: int (indice do eixo j [0 | 1 | 2])
  28 +# k_axis: int (indice do eixo k [0 | 1 | 2])
23 29 def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPosition, laps, frameJump = 5, initialFrame = 18, turn = None):
24 30 sqrt22 = radius * (math.sqrt(2) / 2)
25 31 rad2 = (radius/2)
... ... @@ -71,14 +77,14 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
71 77 pose.location[k_axis] = center[k_axis] + rad2
72 78 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
73 79 currentFrame += frameJump
74   -
  80 +
75 81 if ((l % 8) == 4):
76 82 pose.location[i_axis] = center[i_axis] - radius
77 83 pose.location[j_axis] = center[j_axis]
78   - pose.location[k_axis] = center[k_axis]
  84 + pose.location[k_axis] = center[k_axis]
79 85 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
80 86 currentFrame += frameJump
81   -
  87 +
82 88 if ((l % 8) == 5):
83 89 pose.location[i_axis] = center[i_axis] - sqrt22
84 90 pose.location[j_axis] = center[j_axis] - sqrt22
... ... @@ -93,7 +99,7 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
93 99 pose.location[k_axis] = center[k_axis] - rad2
94 100 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
95 101 currentFrame += frameJump
96   -
  102 +
97 103 if ((l % 8) == 6):
98 104 pose.location[i_axis] = center[i_axis]
99 105 pose.location[j_axis] = center[j_axis] - radius
... ... @@ -106,7 +112,7 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
106 112 pose.location[k_axis] = center[k_axis] - sqrt22
107 113 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
108 114 currentFrame += frameJump
109   -
  115 +
110 116 if ((l % 8) == 7):
111 117 pose.location[i_axis] = center[i_axis] + sqrt22
112 118 pose.location[j_axis] = center[j_axis] - sqrt22
... ... @@ -121,11 +127,9 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
121 127 pose.location[k_axis] = center[k_axis] - rad2
122 128 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
123 129 currentFrame += frameJump
124   - currentFrame -= frameJump
  130 + currentFrame -= frameJump
125 131 return currentFrame
126 132  
127   -
128   -# testing . . .
129 133 def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc, laps, frameJump):
130 134 sqrt22 = radius * math.sqrt(2) / 2
131 135 allLaps = math.floor(8 * laps) + 1
... ... @@ -191,11 +195,7 @@ def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc,
191 195  
192 196 bpy.context.scene.frame_end -= frameJump
193 197  
194   -# testing . . .
195 198 def locationSenoidal(obj):
196   - obj.location = [0, 0, 0]
197   - bpy.context.scene.frame_start = 1
198   - bpy.context.scene.frame_end = 1
199 199 seno = 0
200 200 waveHeight = 5.0
201 201 wave = 5
... ... @@ -208,4 +208,3 @@ def locationSenoidal(obj):
208 208 if (i % 10 == 0):
209 209 obj.keyframe_insert(frame = bpy.context.scene.frame_end, index = -1, data_path = 'location')
210 210 bpy.context.scene.frame_end += 1
211   -
212 211 \ No newline at end of file
... ...
util.py
... ... @@ -2,22 +2,45 @@
2 2  
3 3 import bpy
4 4 import math
  5 +import sys
  6 +import os
5 7  
6   -bones = ["BnMao.R", "BnMao.L"]
7 8 armature = bpy.context.scene.objects.get('Armature.001')
  9 +
  10 +bones = ["BnMao.R", "BnMao.L"]
  11 +
  12 +# Vetor com indices de cada bone do lado direito
8 13 rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66]
  14 +
  15 +# Vetor com indices de cada bone do lado esquerdo
9 16 leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82]
  17 +
  18 +# Vetor com indices de cada bone da face
10 19 faceBonesConf =[15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47]
  20 +
  21 +# Vetor com indices de todos os bones
11 22 allBones = list(range(len(armature.pose.bones)))
12 23  
  24 +def printStackTrace(filename):
  25 + print("\n[Exception]\n File: %s\n Name: %s\n Line: %s\n Type: %s\n Message: %s\n[Exception]\n" % (
  26 + os.path.basename(filename), # os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename),
  27 + sys.exc_info()[2].tb_frame.f_code.co_name,
  28 + sys.exc_info()[2].tb_lineno,
  29 + sys.exc_info()[0].__name__,
  30 + sys.exc_info()[1],
  31 + )
  32 + )
  33 +
  34 +# Função que limpa todos os keyframes e define a quantidade de frames
13 35 def erase_all_keyframes():
14 36 for i in bpy.data.objects:
15 37 i.animation_data_clear()
16 38 bpy.context.scene.frame_start = 1
17 39 bpy.context.scene.frame_current = bpy.context.scene.frame_start
18 40 bpy.context.scene.frame_end = bpy.context.scene.frame_start
19   -
  41 +
20 42 def outconf():
  43 + erase_all_keyframes()
21 44 bpy.context.scene.render.resolution_x = 640
22 45 bpy.context.scene.render.resolution_y = 480
23 46 bpy.context.scene.render.resolution_percentage = 100
... ... @@ -25,16 +48,38 @@ def outconf():
25 48 bpy.context.scene.render.ffmpeg.format = 'MPEG4'
26 49 bpy.context.scene.render.ffmpeg.codec = 'H264'
27 50 # bpy.context.scene.render.filepath = '/tmp/'
28   -
  51 +
  52 +def file_rename(filename):
  53 + from shutil import move
  54 + newFilename = ""
  55 + isValidChar = True
  56 + for char in reversed(filename):
  57 + if (isValidChar == True):
  58 + newFilename += char
  59 + if (char == '_'):
  60 + isValidChar = True
  61 + elif (char == '.'):
  62 + isValidChar = False
  63 + if (len(filename) != len(newFilename)):
  64 + try:
  65 + move(filename, newFilename[::-1])
  66 + return 1
  67 + except Exception as e:
  68 + printStackTrace(__file__)
  69 + return 0
  70 + return 0
  71 +
29 72 def render_sign(userId, signName, beginFrame, endFrame):
30 73 bpy.context.scene.render.filepath = "//users//"+ str(userId)+ "//"+ signName + "_"
31 74 bpy.context.scene.frame_start = beginFrame
32 75 bpy.context.scene.frame_end = endFrame
33   - bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
  76 + outFilename = (bpy.context.scene.render.filepath + "%0.4i-%0.4i.mp4" % (bpy.context.scene.frame_start, bpy.context.scene.frame_end))
  77 + bpy.ops.render.render(animation = True, write_still = False, layer = "", scene = "")
  78 + file_rename(outFilename)
34 79 bpy.ops.wm.quit_blender()
35 80  
36 81 # Função que recupera o frame final do movimento
37   -def get_endFrame(json_input,hands_frames_retilineo):
  82 +def get_endFrame(json_input,hands_frames_retilineo):
38 83 endsFrame = [18]
39 84 if(json_input["rightHand"] != []):
40 85 if(json_input["rightHand"][0] == "circular"):
... ... @@ -44,10 +89,10 @@ def get_endFrame(json_input,hands_frames_retilineo):
44 89 elif(json_input["rightHand"][0] == "retilineo"):
45 90 endsFrame.append(max(hands_frames_retilineo))
46 91 if(json_input["leftHand"] != []):
47   - if(json_input["leftHand"][0] == "circular"):
  92 + if(json_input["leftHand"][0] == "circular"):
48 93 endsFrame.append(int(json_input["leftHand"][4]*8*5+18))
49 94 elif(json_input["leftHand"][0] == "semicircular"):
50 95 endsFrame.append(int(json_input["rightHand"][4]*5*5+18))
51 96 elif(json_input["rightHand"][0] == "retilineo"):
52 97 endsFrame.append(max(hands_frames_retilineo))
53   - return(max(endsFrame))
  98 + return(max(endsFrame))
... ...