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 @@ @@ -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; }
1 # -*- coding: UTF-8 -*- 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 import os 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 sys.path.append(os.getcwd()) 10 sys.path.append(os.getcwd())
9 11
10 -# importa modulos nativos do Blender e Python  
11 -import bpy  
12 -import json  
13 # importa modulos locais 12 # importa modulos locais
14 import util 13 import util
15 import moves 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 # tenta decodificar o argumento JSON recebido 16 # tenta decodificar o argumento JSON recebido
23 try: 17 try:
  18 + util.file_rename("./users/4/teste_circular_0001-0083.mp4")
24 json_input = json.loads(sys.argv[5]) 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 exit(1) 22 exit(1)
28 23
29 # ajusta as configuraçẽs de renderização 24 # ajusta as configuraçẽs de renderização
@@ -38,12 +33,12 @@ hands_frames_retilineo = [30,33] @@ -38,12 +33,12 @@ hands_frames_retilineo = [30,33]
38 armature = bpy.context.scene.objects.get('Armature.001') 33 armature = bpy.context.scene.objects.get('Armature.001')
39 34
40 # Cria uma Action 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 def setPose(actions, parametesConf, positionFrames, bones): 39 def setPose(actions, parametesConf, positionFrames, bones):
45 bpy.ops.object.mode_set(mode = 'OBJECT') 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 bpy.ops.object.mode_set(mode = 'POSE') 42 bpy.ops.object.mode_set(mode = 'POSE')
48 for l in range(len(actions)): 43 for l in range(len(actions)):
49 armature.pose_library = bpy.data.actions[actions[l]] 44 armature.pose_library = bpy.data.actions[actions[l]]
@@ -54,8 +49,8 @@ def setPose(actions, parametesConf, positionFrames, bones): @@ -54,8 +49,8 @@ def setPose(actions, parametesConf, positionFrames, bones):
54 armature.pose.bones[bones[i]].keyframe_insert(data_path = 'rotation_quaternion', index = -1, frame = positionFrames[x]) 49 armature.pose.bones[bones[i]].keyframe_insert(data_path = 'rotation_quaternion', index = -1, frame = positionFrames[x])
55 50
56 # Função responsável por setar pose padrão 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 # Função responsável por setar as configuraçẽs das mãos 55 # Função responsável por setar as configuraçẽs das mãos
61 def generationConfigurations(actions, handParam, positionFrames, bones): 56 def generationConfigurations(actions, handParam, positionFrames, bones):
@@ -72,11 +67,11 @@ initialFrame, endFrame = 15, util.get_endFrame(json_input,hands_frames_retilineo @@ -72,11 +67,11 @@ initialFrame, endFrame = 15, util.get_endFrame(json_input,hands_frames_retilineo
72 #Função que inicia a configuração de ambas as mãos 67 #Função que inicia a configuração de ambas as mãos
73 def configureHands(): 68 def configureHands():
74 # Array com valores dos campos que serão passados pelo JSON 69 # Array com valores dos campos que serão passados pelo JSON
75 - hands = ["rightHand", "leftHand"] 70 + hands = ["rightHand", "leftHand"]
76 iks = ['ik_FK.R', 'ik_FK.L'] 71 iks = ['ik_FK.R', 'ik_FK.L']
77 bones_ = [util.rightBonesConf, util.leftBonesConf] 72 bones_ = [util.rightBonesConf, util.leftBonesConf]
78 #Array com as actions FAKES que seram selecionadas no Blender para cada lado do corpo 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 global endFrame 75 global endFrame
81 for i in range(len(hands)): 76 for i in range(len(hands)):
82 if(json_input[hands[i]] != []): 77 if(json_input[hands[i]] != []):
@@ -93,19 +88,27 @@ def configureHands(): @@ -93,19 +88,27 @@ def configureHands():
93 elif(move == "retilineo"): 88 elif(move == "retilineo"):
94 generationConfigurations(actions[i], json_input[hands[i]][-6:-3], hands_default_frames, bones_[i]) 89 generationConfigurations(actions[i], json_input[hands[i]][-6:-3], hands_default_frames, bones_[i])
95 generationConfigurations(actions[i], json_input[hands[i]][-3:],hands_frames_retilineo, bones_[i]) 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 # Função que inicia a configuração da face 101 # Função que inicia a configuração da face
99 -def configureFace(): 102 +def configureFace():
100 global endFrame 103 global endFrame
101 if(json_input["facialExp"] != []): 104 if(json_input["facialExp"] != []):
102 # Set face 105 # Set face
103 - faceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf) 106 + faceConfiguration(json_input["facialExp"], [endFrame/4], util.faceBonesConf)
104 107
105 # Default Pose 108 # Default Pose
106 print(endFrame) 109 print(endFrame)
107 -poseDefault([1, endFrame+15], util.allBones) 110 +poseDefault([1, endFrame + 15], util.allBones)
108 configureHands() 111 configureHands()
109 configureFace() 112 configureFace()
110 113
111 -util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25)  
112 \ No newline at end of file 114 \ No newline at end of file
  115 +util.render_sign(json_input["userId"], json_input["signName"], 1, endFrame + 25)
1 # -*- coding: UTF-8 -*- 1 # -*- coding: UTF-8 -*-
  2 +
2 import math 3 import math
3 4
4 def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensity = 5, initialFrame = 18, turn = None): 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,7 +8,7 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi
7 if(direction == 'horario'): 8 if(direction == 'horario'):
8 endFrame = moves.locationCircular(center, radius, 1, 0, 2, pose, 0, laps, intensity, initialFrame,turn) 9 endFrame = moves.locationCircular(center, radius, 1, 0, 2, pose, 0, laps, intensity, initialFrame,turn)
9 else: 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 elif(orientation == 'paralelo'): 12 elif(orientation == 'paralelo'):
12 if(direction == 'horario'): 13 if(direction == 'horario'):
13 endFrame = moves.locationCircular(center, radius, 1, 2, 0, pose, 0, laps, intensity, initialFrame,turn) 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,6 +21,11 @@ def circular_or_semiCircular(pose, orientation, direction, radius, laps, intensi
20 endFrame = moves.locationCircular(center, radius, 0, 2, 1, pose, 0, laps, intensity, initialFrame,turn) 21 endFrame = moves.locationCircular(center, radius, 0, 2, 1, pose, 0, laps, intensity, initialFrame,turn)
21 return endFrame 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 def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPosition, laps, frameJump = 5, initialFrame = 18, turn = None): 29 def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPosition, laps, frameJump = 5, initialFrame = 18, turn = None):
24 sqrt22 = radius * (math.sqrt(2) / 2) 30 sqrt22 = radius * (math.sqrt(2) / 2)
25 rad2 = (radius/2) 31 rad2 = (radius/2)
@@ -71,14 +77,14 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi @@ -71,14 +77,14 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
71 pose.location[k_axis] = center[k_axis] + rad2 77 pose.location[k_axis] = center[k_axis] + rad2
72 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location') 78 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
73 currentFrame += frameJump 79 currentFrame += frameJump
74 - 80 +
75 if ((l % 8) == 4): 81 if ((l % 8) == 4):
76 pose.location[i_axis] = center[i_axis] - radius 82 pose.location[i_axis] = center[i_axis] - radius
77 pose.location[j_axis] = center[j_axis] 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 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location') 85 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
80 currentFrame += frameJump 86 currentFrame += frameJump
81 - 87 +
82 if ((l % 8) == 5): 88 if ((l % 8) == 5):
83 pose.location[i_axis] = center[i_axis] - sqrt22 89 pose.location[i_axis] = center[i_axis] - sqrt22
84 pose.location[j_axis] = center[j_axis] - sqrt22 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,7 +99,7 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
93 pose.location[k_axis] = center[k_axis] - rad2 99 pose.location[k_axis] = center[k_axis] - rad2
94 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location') 100 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
95 currentFrame += frameJump 101 currentFrame += frameJump
96 - 102 +
97 if ((l % 8) == 6): 103 if ((l % 8) == 6):
98 pose.location[i_axis] = center[i_axis] 104 pose.location[i_axis] = center[i_axis]
99 pose.location[j_axis] = center[j_axis] - radius 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,7 +112,7 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
106 pose.location[k_axis] = center[k_axis] - sqrt22 112 pose.location[k_axis] = center[k_axis] - sqrt22
107 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location') 113 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
108 currentFrame += frameJump 114 currentFrame += frameJump
109 - 115 +
110 if ((l % 8) == 7): 116 if ((l % 8) == 7):
111 pose.location[i_axis] = center[i_axis] + sqrt22 117 pose.location[i_axis] = center[i_axis] + sqrt22
112 pose.location[j_axis] = center[j_axis] - sqrt22 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,11 +127,9 @@ def locationCircular(center, radius, i_axis, j_axis, k_axis, pose, initialPositi
121 pose.location[k_axis] = center[k_axis] - rad2 127 pose.location[k_axis] = center[k_axis] - rad2
122 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location') 128 pose.keyframe_insert(frame = currentFrame, index = -1, data_path = 'location')
123 currentFrame += frameJump 129 currentFrame += frameJump
124 - currentFrame -= frameJump 130 + currentFrame -= frameJump
125 return currentFrame 131 return currentFrame
126 132
127 -  
128 -# testing . . .  
129 def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc, laps, frameJump): 133 def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc, laps, frameJump):
130 sqrt22 = radius * math.sqrt(2) / 2 134 sqrt22 = radius * math.sqrt(2) / 2
131 allLaps = math.floor(8 * laps) + 1 135 allLaps = math.floor(8 * laps) + 1
@@ -191,11 +195,7 @@ def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc, @@ -191,11 +195,7 @@ def locationHelicoidal(center, startRadius, incRadius, x, y, z,pose, currentLoc,
191 195
192 bpy.context.scene.frame_end -= frameJump 196 bpy.context.scene.frame_end -= frameJump
193 197
194 -# testing . . .  
195 def locationSenoidal(obj): 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 seno = 0 199 seno = 0
200 waveHeight = 5.0 200 waveHeight = 5.0
201 wave = 5 201 wave = 5
@@ -208,4 +208,3 @@ def locationSenoidal(obj): @@ -208,4 +208,3 @@ def locationSenoidal(obj):
208 if (i % 10 == 0): 208 if (i % 10 == 0):
209 obj.keyframe_insert(frame = bpy.context.scene.frame_end, index = -1, data_path = 'location') 209 obj.keyframe_insert(frame = bpy.context.scene.frame_end, index = -1, data_path = 'location')
210 bpy.context.scene.frame_end += 1 210 bpy.context.scene.frame_end += 1
211 -  
212 \ No newline at end of file 211 \ No newline at end of file
@@ -2,22 +2,45 @@ @@ -2,22 +2,45 @@
2 2
3 import bpy 3 import bpy
4 import math 4 import math
  5 +import sys
  6 +import os
5 7
6 -bones = ["BnMao.R", "BnMao.L"]  
7 armature = bpy.context.scene.objects.get('Armature.001') 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 rightBonesConf = [1, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66] 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 leftBonesConf = [0, 43, 44, 45, 46, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82] 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 faceBonesConf =[15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 47] 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 allBones = list(range(len(armature.pose.bones))) 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 def erase_all_keyframes(): 35 def erase_all_keyframes():
14 for i in bpy.data.objects: 36 for i in bpy.data.objects:
15 i.animation_data_clear() 37 i.animation_data_clear()
16 bpy.context.scene.frame_start = 1 38 bpy.context.scene.frame_start = 1
17 bpy.context.scene.frame_current = bpy.context.scene.frame_start 39 bpy.context.scene.frame_current = bpy.context.scene.frame_start
18 bpy.context.scene.frame_end = bpy.context.scene.frame_start 40 bpy.context.scene.frame_end = bpy.context.scene.frame_start
19 - 41 +
20 def outconf(): 42 def outconf():
  43 + erase_all_keyframes()
21 bpy.context.scene.render.resolution_x = 640 44 bpy.context.scene.render.resolution_x = 640
22 bpy.context.scene.render.resolution_y = 480 45 bpy.context.scene.render.resolution_y = 480
23 bpy.context.scene.render.resolution_percentage = 100 46 bpy.context.scene.render.resolution_percentage = 100
@@ -25,16 +48,38 @@ def outconf(): @@ -25,16 +48,38 @@ def outconf():
25 bpy.context.scene.render.ffmpeg.format = 'MPEG4' 48 bpy.context.scene.render.ffmpeg.format = 'MPEG4'
26 bpy.context.scene.render.ffmpeg.codec = 'H264' 49 bpy.context.scene.render.ffmpeg.codec = 'H264'
27 # bpy.context.scene.render.filepath = '/tmp/' 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 def render_sign(userId, signName, beginFrame, endFrame): 72 def render_sign(userId, signName, beginFrame, endFrame):
30 bpy.context.scene.render.filepath = "//users//"+ str(userId)+ "//"+ signName + "_" 73 bpy.context.scene.render.filepath = "//users//"+ str(userId)+ "//"+ signName + "_"
31 bpy.context.scene.frame_start = beginFrame 74 bpy.context.scene.frame_start = beginFrame
32 bpy.context.scene.frame_end = endFrame 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 bpy.ops.wm.quit_blender() 79 bpy.ops.wm.quit_blender()
35 80
36 # Função que recupera o frame final do movimento 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 endsFrame = [18] 83 endsFrame = [18]
39 if(json_input["rightHand"] != []): 84 if(json_input["rightHand"] != []):
40 if(json_input["rightHand"][0] == "circular"): 85 if(json_input["rightHand"][0] == "circular"):
@@ -44,10 +89,10 @@ def get_endFrame(json_input,hands_frames_retilineo): @@ -44,10 +89,10 @@ def get_endFrame(json_input,hands_frames_retilineo):
44 elif(json_input["rightHand"][0] == "retilineo"): 89 elif(json_input["rightHand"][0] == "retilineo"):
45 endsFrame.append(max(hands_frames_retilineo)) 90 endsFrame.append(max(hands_frames_retilineo))
46 if(json_input["leftHand"] != []): 91 if(json_input["leftHand"] != []):
47 - if(json_input["leftHand"][0] == "circular"): 92 + if(json_input["leftHand"][0] == "circular"):
48 endsFrame.append(int(json_input["leftHand"][4]*8*5+18)) 93 endsFrame.append(int(json_input["leftHand"][4]*8*5+18))
49 elif(json_input["leftHand"][0] == "semicircular"): 94 elif(json_input["leftHand"][0] == "semicircular"):
50 endsFrame.append(int(json_input["rightHand"][4]*5*5+18)) 95 endsFrame.append(int(json_input["rightHand"][4]*5*5+18))
51 elif(json_input["rightHand"][0] == "retilineo"): 96 elif(json_input["rightHand"][0] == "retilineo"):
52 endsFrame.append(max(hands_frames_retilineo)) 97 endsFrame.append(max(hands_frames_retilineo))
53 - return(max(endsFrame)) 98 + return(max(endsFrame))