Newer
Older
#!/usr/bin/python3
# To change this template, choose Tools | Templates
# and open the template in the editor.
# ***** GPL LICENSE BLOCK *****
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# All rights reserved.
# ***** GPL LICENSE BLOCK *****
bl_info = {
"name": "Import: Sound to Animation",
"author": "Vlassius",
"version": (0, 80),
"blender": (2, 80, 0),
"location": "Select a object > View3D > Tool Shelf > Import Movement From .Wav File",
"description": "Extract movement from .wav sound file.",
"doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
CoDEmanX
committed
"Scripts/Import-Export/Import_Movement_From_Audio_File",
"tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
-- Extract movement from sound file, to help in animation - import script --<br>
- NOTES:
- This script takes a wav file and get sound "movement" to help you in sync the movement to words in the wave file. <br>
- Supported Audio: .wav (wave) 8 bits and 16 bits - mono and multichanel file<br>
- At least Blender 2.80 is necessary to run this program.
- Brazil
"""
import bpy
from bpy.props import *
#from io_utils import ImportHelper
import wave
def _Interna_Globals(BytesDadosTotProcess, context):
global array
array= bytearray(BytesDadosTotProcess) # cria array
arrayAutoSense= bytearray((BytesDadosTotProcess)*2) # cria array para AutoAudioSense
context.object.imp_sound_to_anim.bArrayCriado=True
#==================================================================================================
# BLENDER UI Panel
#==================================================================================================
"""class VIEW3D_PT_CustomMenuPanel(bpy.types.Panel):
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
bl_label = "Import Movement From Wav File"
class VIEW3D_PT_SoundPanel(bpy.types.Panel):
bl_idname = "IMPORTWAVTOOL_PT_tools"
bl_space_type = "VIEW_3D"
bl_context = "objectmode"
bl_region_type = "UI"
bl_label = "Import Tool"
bl_category = "Animate"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
b=bpy.context.active_object.type=='EMPTY' or bpy.context.active_object.type=='ARMATURE' or \
bpy.context.active_object.type=='MESH' or \
bpy.context.active_object.type=='CAMERA' or \
bpy.context.active_object.type=='LAMP'
row.label(text="The Selected Object is: type \"" + bpy.context.active_object.type + \
"\", and it is not supported.")
row.label(text="Supported Object are Type: Armature, Mesh, Camera and Lamp")
#print(context.object.imp_sound_to_anim.bTypeImport)
if context.object.imp_sound_to_anim.bTypeImport == 0:
#mount panel to Direct animation
row=layout.row()
layout.operator("import.sound_animation_botao_udirect")
# monta as telas quando está rodando
elif context.object.imp_sound_to_anim.Working!="": #its running
if context.object.imp_sound_to_anim.Working== "CheckSmartRender":
#context.object.imp_sound_to_anim.Info_check_smartrender=
row=layout.row()
row.label(text="Checking for Smart Render...")
row=layout.row()
row.label(text=context.object.imp_sound_to_anim.Info_check_smartrender)
elif context.object.imp_sound_to_anim.Working== "SmartRender":
#context.object.imp_sound_to_anim.Info_check_smartrender=
row=layout.row()
row.label(text="Processing Smart Render...")
row=layout.row()
row.label(text=context.object.imp_sound_to_anim.Info_check_smartrender)
elif context.object.imp_sound_to_anim.Working== "ProcessaSom":
#context.object.imp_sound_to_anim.Info_Import=
row=layout.row()
row.label(text="Processing Sound File...")
row=layout.row()
row.label(text=context.object.imp_sound_to_anim.Info_Import)
elif context.object.imp_sound_to_anim.Working== "wavimport":
#context.object.imp_sound_to_anim.Info_Import=
row=layout.row()
row.label(text="Importing Keys...")
row=layout.row()
row.label(text=context.object.imp_sound_to_anim.Info_Import)
row=layout.row()
# botao cancel
layout.operator(OBJECT_OT_Botao_Cancel.bl_idname)
elif context.object.imp_sound_to_anim.bTypeImport == 1:
row.label(text="2)Click Button \"Import Key Frames\",")
row.label(text="Run the animation and Enjoy!")
row.prop(context.object.imp_sound_to_anim,"action_auto_audio_sense")
if context.object.imp_sound_to_anim.action_auto_audio_sense == 0: # se auto audio sense desligado
row.prop(context.object.imp_sound_to_anim,"audio_sense")
if context.object.imp_sound_to_anim.remove_beat == 0 :
row.prop(context.object.imp_sound_to_anim,"use_just_beat")
if context.object.imp_sound_to_anim.use_just_beat == 0:
row.prop(context.object.imp_sound_to_anim,"remove_beat")
if context.object.imp_sound_to_anim.use_just_beat or context.object.imp_sound_to_anim.remove_beat:
if not context.object.imp_sound_to_anim.beat_less_sensible and not context.object.imp_sound_to_anim.beat_more_sensible:
if context.object.imp_sound_to_anim.beat_less_sensible ==0:
row.prop(context.object.imp_sound_to_anim,"beat_more_sensible")
if context.object.imp_sound_to_anim.beat_more_sensible ==0:
row.prop(context.object.imp_sound_to_anim,"beat_less_sensible")
row.prop(context.object.imp_sound_to_anim,"action_per_second")
row.prop(context.object.imp_sound_to_anim,"action_escale")
row.label(text="Result from 0 to " + str(round(255/context.object.imp_sound_to_anim.action_escale,4)) + "")
row.prop(context.object.imp_sound_to_anim,"import_type")
row.prop(context.object.imp_sound_to_anim,"import_where1")
row.prop(context.object.imp_sound_to_anim,"import_where2")
row.prop(context.object.imp_sound_to_anim,"import_where3")
row.prop(context.object.imp_sound_to_anim,"frames_per_second")
split=column.split(factor=0.5) #percentage=0.5
row.prop(context.object.imp_sound_to_anim,"frames_initial")
row.prop(context.object.imp_sound_to_anim,"action_min_value")
row.prop(context.object.imp_sound_to_anim,"optimization_destructive")
row.prop(context.object.imp_sound_to_anim,"action_max_value")
row.prop(context.object.imp_sound_to_anim,"action_offset_x")
row.prop(context.object.imp_sound_to_anim,"action_offset_y")
row.prop(context.object.imp_sound_to_anim,"action_offset_z")
row.prop(context.object.imp_sound_to_anim,"audio_channel_select")
row.prop(context.object.imp_sound_to_anim,"action_valor_igual")
#operator button
#OBJECT_OT_Botao_Go => Botao_GO
row=layout.row()
layout.operator(OBJECT_OT_Botao_Go.bl_idname)
row.label(text=context.object.imp_sound_to_anim.Info_Import)
# preciso garantir a existencia do array porque o Blender salva no arquivo como existente sem o array existir
try:
array
except NameError:
nada=0 #dummy
else:
if context.object.imp_sound_to_anim.bArrayCriado:
layout.operator(OBJECT_OT_Botao_Import.bl_idname)
row=layout.row()
#Layout SmartRender, somente para Blender_render
if bpy.context.scene.render.engine == "BLENDER_RENDER":
row.label(text="----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------")
row=layout.row()
if context.object.imp_sound_to_anim.Info_check_smartrender!= "":
row.label(text=context.object.imp_sound_to_anim.Info_check_smartrender)
row=layout.row()
row.operator(OBJECT_OT_Botao_Check_SmartRender.bl_idname)
if context.object.imp_sound_to_anim.Info_check_smartrender!= "":
row.prop(context.object.imp_sound_to_anim,"check_smartrender_loc_rot_sc")
row.prop(context.object.imp_sound_to_anim,"check_smartrender_material_basic")
row.prop(context.object.imp_sound_to_anim,"check_smartrender_material_transparence")
row.prop(context.object.imp_sound_to_anim,"check_smartrender_material_mirror")
#-----------------------------
#Use Driver
if context.object.imp_sound_to_anim.bTypeImport == 2:
#row.prop(context.object.imp_sound_to_anim,"audio_sense")
#row=layout.row()
#row.prop(context.object.imp_sound_to_anim,"frames_per_second")
#row=layout.row()
#row.prop(context.object.imp_sound_to_anim,"action_per_second")
#row=layout.row()
#layout.operator(ImportWavFile.bl_idname)
#
#==================================================================================================
# BLENDER UI PropertyGroup
#==================================================================================================
#
bArrayCriado: IntProperty(name="",
description="Avisa que rodou process de som",
default=0)
Working: StringProperty(name="Working",
description="Script esta trabalhando",
maxlen= 1024,
default="")
Info_Import: StringProperty(name="Info_Import",
description="Info about Import",
maxlen= 1024,
default= "")#this set the initial text
Info_check_smartrender: StringProperty(name="Info_check_smartrender",
description="Smart Render Message",
maxlen= 1024,
default= "")#this set the initial text
#iAudioSensib=0 #sensibilidade volume do audio 0 a 5. Quanto maior, mais sensibilidade
audio_sense: IntProperty(name="Audio Sens",
description="Audio Sensibility",
#iFramesPorSeg=15 #Frames por segundo para key frame
#fps= (bpy.types.Scene) bpy.context.object.render.fps
frames_per_second: IntProperty(name="#Frames/s",
description="Frames you want per second. Better match your set up in Blender scene",
#iMovPorSeg=1 #Sensibilidade de movimento. 3= 3 movimentos por segundo
action_per_second: IntProperty(name="Act/s",
description="Actions per second. From 1 to #Frames/s",
#iDivScala=200
#scala do valor do movimento. [se =1 - 0 a 255 ] [se=255 - 0,00000 a 1,00000] [se=1000 - 0 a 0.255]
action_escale: IntProperty(name="Scale",
description="Scale the result values. See the text at right side of the field",
action_max_value: IntProperty(name="Clip Max",
description="Set the max value (clip higher values)",
action_min_value: IntProperty(name="Clip Min",
description="Set the min value. (clip lower values)",
min=0,
max=255,
frames_initial: IntProperty(name="Frame Ini",
description="Where to start to put the computed values",
audio_channel_select: IntProperty(name="Audio Channel",
description="Choose the audio channel to use",
min=1,
max=10,
action_offset_x: FloatProperty(name="XOffset",
description="Offset X Values",
min=-999999,
max=999999,
action_offset_y: FloatProperty(name="YOffset",
description="Offset Y Values",
min=-999999,
max=999999,
action_offset_z: FloatProperty(name="ZOffset",
description="Offset Z Values",
min=-999999,
max=999999,
import_type: EnumProperty(items=(('imp_t_Scale', "Scale", "Apply to Scale"),
('imp_t_Rotation', "Rotation", "Apply to Rotation"),
name="",
description= "Property to Import Values",
import_where1: EnumProperty(items=(('imp_w_-z', "-z", "Apply to -z"),
('imp_w_-y', "-y", "Apply to -y"),
('imp_w_-x', "-x", "Apply to -x"),
('imp_w_z', "z", "Apply to z"),
('imp_w_y', "y", "Apply to y"),
('imp_w_x', "x", "Apply to x")
),
description= "Where to Import",
default='imp_w_z')
import_where2: EnumProperty(items=(('imp_w_none', "None", ""),
('imp_w_-z', "-z", "Apply to -z"),
('imp_w_-y', "-y", "Apply to -y"),
('imp_w_-x', "-x", "Apply to -x"),
('imp_w_z', "z", "Apply to z"),
('imp_w_y', "y", "Apply to y"),
('imp_w_x', "x", "Apply to x")
),
name="",
description= "Where to Import",
default='imp_w_none')
import_where3: EnumProperty(items=(('imp_w_none', "None", ""),
('imp_w_-z', "-z", "Apply to -z"),
('imp_w_-y', "-y", "Apply to -y"),
('imp_w_-x', "-x", "Apply to -x"),
('imp_w_z', "z", "Apply to z"),
('imp_w_y', "y", "Apply to y"),
('imp_w_x', "x", "Apply to x")
),
name="",
description= "Where to Import",
default='imp_w_none')
#========== Propriedades boolean =============#
# INVERTIDO!!! bNaoValorIgual=True # nao deixa repetir valores INVERTIDO!!!
action_valor_igual: BoolProperty(name="Hard Transition",
description="Default. Movements like a beat",
action_auto_audio_sense: BoolProperty(name="Auto Audio Sensitivity",
description="Try to discover best audio scale. ",
default=1)
use_just_beat:BoolProperty(name="Only Use The Beat",
description="Try to use only the beat to extract movement",
remove_beat:BoolProperty(name="Remove The Beat",
description="Try to remove the beat to extract movement",
beat_more_sensible:BoolProperty(name="More Sensible",
description="Try To be more sensible about the beat",
beat_less_sensible:BoolProperty(name="Less Sensible",
description="Try to be less sensible about the beat",
check_smartrender_loc_rot_sc:BoolProperty(name="Loc Rot Scale",
description="Find changes in Location, Rotation and Scale Frame by Frame",
check_smartrender_material_basic:BoolProperty(name="Basic Material",
description="Find changes in basic material settings Frame by Frame",
check_smartrender_material_transparence:BoolProperty(name="Material Transparence",
description="Find changes in material transparence settings Frame by Frame",
check_smartrender_material_mirror:BoolProperty(name="Material Mirror",
description="Find changes in material mirror settings Frame by Frame",
timer_reset_func:BoolProperty(name="Reset Counters",
description="Reset Counters after stop",
default=0)
cancel_button_hit:BoolProperty(name="Cancel Hit",
optimization_destructive: IntProperty(name="Optimization",
description="Hi value = Hi optimization -> Hi loss of information",
bTypeImport: IntProperty(name="bTypeImport",
filter_glob: StringProperty(default="*.wav", options={'HIDDEN'})
path: StringProperty(name="File Path", description="Filepath used for importing the WAV file", \
filename: StringProperty(name="File Name", description="Name of the file")
directory: StringProperty(name="Directory", description="Directory of the file")
def WavFileImport(self, context):
self.layout.operator(ImportWavFile.bl_idname, text="Import a wav file", icon='PLUGIN')
#==================================================================================================
# Use Direct
#==================================================================================================
#
class OBJECT_OT_Botao_uDirect(bpy.types.Operator):
'''Import as Direct Animation'''
bl_idname = "import.sound_animation_botao_udirect"
bl_label = "Direct to a Property"
def execute(self, context):
context.object.imp_sound_to_anim.bTypeImport= 1
if context.object.imp_sound_to_anim.frames_per_second == 0:
context.object.imp_sound_to_anim.frames_per_second= bpy.context.scene.render.fps
def invoke(self, context, event):
self.execute(context)
#==================================================================================================
# Button - Import
#==================================================================================================
#
class OBJECT_OT_Botao_Import(bpy.types.Operator):
'''Import Key Frames to Blender'''
bl_idname = "import.sound_animation_botao_import"
bl_label = "Import Key Frames"
RunFrom=0
iSumImportFrames=0
iSumOptimizerP1=0
iSumOptimizerP2=0
iSumOptimizerP3=0
def wavimport(context, loop):
obi=OBJECT_OT_Botao_Import
# para de entrar no timer
context.object.imp_sound_to_anim.Working=""
if context.object.imp_sound_to_anim.timer_reset_func:
obi.RunFrom=0
obi.iSumOptimizerP1=0
obi.iSumOptimizerP2=0
obi.iSumOptimizerP3=0
obi.iSumImportFrames=0
context.object.imp_sound_to_anim.timer_reset_func=False
#limita o loop se estiver no fim
tot=len(array)-1
if obi.RunFrom+loop > tot:
loop= tot - obi.RunFrom
#scala do valor do movimento. [se =1 - 0 a 255 ] [se=255 - 0,00000 a 1,00000] [se=1000 - 0 a 0.255]
iDivScala= int(context.object.imp_sound_to_anim.action_escale)
# nao deixa repetir valores
bNaoValorIgual=True
if context.object.imp_sound_to_anim.action_valor_igual: bNaoValorIgual= False
# inicia no inicio pedido pelo usuario mais ponteiro RunFrom
iStartFrame= int(context.object.imp_sound_to_anim.frames_initial) + obi.RunFrom
iMaxValue= context.object.imp_sound_to_anim.action_max_value
iMinValue= context.object.imp_sound_to_anim.action_min_value
if context.object.imp_sound_to_anim.import_type=='imp_t_Scale':
if context.object.imp_sound_to_anim.import_type=='imp_t_Rotation':
if context.object.imp_sound_to_anim.import_type=='imp_t_Location':
bEixo=True;
# atencao, nao eh boolean
iEixoXneg= iEixoYneg= iEixoZneg=1
# atencao, nao eh boolean
iRotationNeg=1
# atencao, nao eh boolean
iEscalaYneg= iEscalaZneg= iEscalaXneg=1
bEixoX=bEixoY=bEixoZ=bEscalaX=bEscalaY=bEscalaZ=bRotationX=bRotationY=bRotationZ=False
# LOCAL 1
if context.object.imp_sound_to_anim.import_where1== 'imp_w_x':
bEixoX=True
bEscalaX=True
bRotationX=True
if context.object.imp_sound_to_anim.import_where1== 'imp_w_y':
bEixoY=True
bEscalaY=True
bRotationY=True
if context.object.imp_sound_to_anim.import_where1== 'imp_w_z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
if context.object.imp_sound_to_anim.import_where1== 'imp_w_-x':
bEixoX=True
bEscalaX=True
bRotationX=True
iEixoXneg=-1
iEscalaXneg=-1
iRotationNeg=-1
if context.object.imp_sound_to_anim.import_where1== 'imp_w_-y':
bEixoY=True
bEscalaY=True
bRotationY=True
iEixoYneg=-1
iRotationNeg=-1
iEscalaYneg=-1
if context.object.imp_sound_to_anim.import_where1== 'imp_w_-z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
iEixoZneg=-1
iRotationNeg=-1
iEscalaZneg=-1
# LOCAL 2
if context.object.imp_sound_to_anim.import_where2== 'imp_w_x':
bEixoX=True
bEscalaX=True
bRotationX=True
if context.object.imp_sound_to_anim.import_where2== 'imp_w_y':
bEixoY=True
bEscalaY=True
bRotationY=True
if context.object.imp_sound_to_anim.import_where2== 'imp_w_z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
if context.object.imp_sound_to_anim.import_where2== 'imp_w_-x':
bEixoX=True
bEscalaX=True
bRotationX=True
iEixoXneg=-1
iEscalaXneg=-1
iRotationNeg=-1
if context.object.imp_sound_to_anim.import_where2== 'imp_w_-y':
bEixoY=True
bEscalaY=True
bRotationY=True
iEixoYneg=-1
iRotationNeg=-1
iEscalaYneg=-1
if context.object.imp_sound_to_anim.import_where2== 'imp_w_-z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
iEixoZneg=-1
iRotationNeg=-1
iEscalaZneg=-1
# LOCAL 3
if context.object.imp_sound_to_anim.import_where3== 'imp_w_x':
bEixoX=True
bEscalaX=True
bRotationX=True
if context.object.imp_sound_to_anim.import_where3== 'imp_w_y':
bEixoY=True
bEscalaY=True
bRotationY=True
if context.object.imp_sound_to_anim.import_where3== 'imp_w_z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
if context.object.imp_sound_to_anim.import_where3== 'imp_w_-x':
bEixoX=True
bEscalaX=True
bRotationX=True
iEixoXneg=-1
iEscalaXneg=-1
iRotationNeg=-1
if context.object.imp_sound_to_anim.import_where3== 'imp_w_-y':
bEixoY=True
bEscalaY=True
bRotationY=True
iEixoYneg=-1
iRotationNeg=-1
iEscalaYneg=-1
if context.object.imp_sound_to_anim.import_where3== 'imp_w_-z':
bEixoZ=True
bEscalaZ=True
bRotationZ=True
iEixoZneg=-1
iRotationNeg=-1
iEscalaZneg=-1
iMinBaseX=iMinScaleBaseX=context.object.imp_sound_to_anim.action_offset_x
iMinBaseY=iMinScaleBaseY=context.object.imp_sound_to_anim.action_offset_y
iMinBaseZ=iMinScaleBaseZ=context.object.imp_sound_to_anim.action_offset_z
iRotationAxisBaseX=context.object.imp_sound_to_anim.action_offset_x +1
iRotationAxisBaseY=context.object.imp_sound_to_anim.action_offset_y +1
iRotationAxisBaseZ=context.object.imp_sound_to_anim.action_offset_z +1
#Added destructive optimizer option - LostLestSignificativeDigit lost/total
iDestructiveOptimizer=context.object.imp_sound_to_anim.optimization_destructive
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
#limita ou nao o valor - velocidade
bLimitValue=False
if iMinValue<0: iMinValue=0
if iMaxValue>255: iMaxValue=255
if iMinValue>255: iMinValue=255
if iMaxValue<0: iMaxValue=0
if iMinValue!= 0: bLimitValue= True
if iMaxValue!= 255: bLimitValue= True
if obi.RunFrom==0:
print('')
print("================================================================")
from time import strftime
print(strftime("Start Import: %H:%M:%S"))
print("================================================================")
print('')
ilocationXAnt=0
ilocationYAnt=0
ilocationZAnt=0
iscaleXAnt=0
iscaleYAnt=0
iscaleZAnt=0
iRotateValAnt=0
# variavel global _Interna_Globals
if context.object.imp_sound_to_anim.bArrayCriado:
for i in range(loop):
ival=array[i+obi.RunFrom]/iDivScala
#valor pequeno demais, vai dar zero na hora de aplicar
if ival < 0.001:
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
# to increase performance and legibility
arrayI= array[i+obi.RunFrom]
arrayIP1= array[i+1+obi.RunFrom]
arrayIL1= array[i-1+obi.RunFrom]
# opcao de NAO colocar valores iguais sequenciais
if i>0 and bNaoValorIgual and arrayIL1== arrayI:
print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + \
"\t(skipped by optimizer)")
obi.iSumOptimizerP3+=1
else:
# otimizacao - nao preciso mais que 2 valores iguais.
# pular key frame intermediario - Ex b, a, -, -, -, a
# tambem otimiza pelo otimizador com perda
# valor atual == anterior e posterior -> pula
if i>0 and i< len(array)-1 and abs(arrayI - arrayIL1)<=iDestructiveOptimizer and \
abs(arrayI - arrayIP1)<=iDestructiveOptimizer:
print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + \
"\t(skipped by optimizer)")
if iDestructiveOptimizer>0 and arrayI != arrayIL1 or arrayI != arrayIP1:
obi.iSumOptimizerP1+=1
else: obi.iSumOptimizerP2+=1
else:
if bLimitValue:
if arrayI > iMaxValue: array[i+obi.RunFrom]=iMaxValue
if arrayI < iMinValue: array[i+obi.RunFrom]=iMinValue
ival=array[i+obi.RunFrom]/iDivScala
#passa para float com somente 3 digitos caso seja float
m_ival=ival*1000
if int(m_ival) != m_ival:
ival= int(m_ival)
ival = ival /1000
bpy.context.scene.frame_current = i+iStartFrame
#precisa fazer objeto ativo
if bpy.context.active_object.type=='MESH' or bpy.context.active_object.type=='CAMERA' or \
bpy.context.active_object.type=='EMPTY':
if bEixo:
if bEixoX: bpy.context.active_object.location.x = ival*iEixoXneg+iMinBaseX
if bEixoY: bpy.context.active_object.location.y = ival*iEixoYneg+iMinBaseY
if bEixoZ: bpy.context.active_object.location.z = ival*iEixoZneg+iMinBaseZ
if bEscala:
if bEscalaX: bpy.context.active_object.scale.x = ival*iEscalaXneg+iMinScaleBaseX
if bEscalaY: bpy.context.active_object.scale.y = ival*iEscalaYneg+iMinScaleBaseY
if bEscalaZ: bpy.context.active_object.scale.z = ival*iEscalaZneg+iMinScaleBaseZ
# 'ARMATURE' or ('MESH' and bRotacao) or ('CAMERA' and bRotacao) or 'LAMP' or 'EMPTY' and bRotacao)
if bpy.context.active_object.type=='ARMATURE' or (bpy.context.active_object.type=='MESH' and bRotacao) or \
(bpy.context.active_object.type=='CAMERA' and bRotacao) or \
bpy.context.active_object.type=='LAMP' or \
(bpy.context.active_object.type=='EMPTY' and bRotacao):
#=========== BONE ===========#
if bpy.context.active_object.type=='ARMATURE': #precisa ser objeto ativo. Nao achei como passar para editmode
if bpy.context.mode!= 'POSE': #posemode
bpy.ops.object.posemode_toggle()
#============= ALL ===========#
if bEixo:
if ilocationXAnt!=0 or ilocationYAnt!=0 or ilocationZAnt!=0:
bpy.ops.transform.translate(value=(ilocationXAnt*-1, ilocationYAnt*-1, \
ilocationZAnt*-1), constraint_axis=(bEixoX, bEixoY,bEixoZ), \
orient_type='GLOBAL', mirror=False, \
proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
proportional_size=1, snap=False, \
snap_target='CLOSEST', snap_point=(0, 0, 0), \
snap_align=False, snap_normal=(0, 0, 0), \
release_confirm=False)
ilocationX=ilocationY=ilocationZ=0
if bEixoX: ilocationX = ival*iEixoXneg+iMinBaseX
if bEixoY: ilocationY = ival*iEixoYneg+iMinBaseY
if bEixoZ: ilocationZ = ival*iEixoZneg+iMinBaseZ
bpy.ops.transform.translate(value=(ilocationX, ilocationY, \
ilocationZ), constraint_axis=(bEixoX, bEixoY,bEixoZ), \
orient_type='GLOBAL', mirror=False, \
proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
proportional_size=1, snap=False, \
snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, \
snap_normal=(0, 0, 0), release_confirm=False)
ilocationXAnt= ilocationX
ilocationYAnt= ilocationY
ilocationZAnt= ilocationZ
if bEscala:
if iscaleXAnt!=0 or iscaleYAnt!=0 or iscaleZAnt!=0:
tmpscaleXAnt=0
tmpscaleYAnt=0
tmpscaleZAnt=0
if iscaleXAnt: tmpscaleXAnt=1/iscaleXAnt
if iscaleYAnt: tmpscaleYAnt=1/iscaleYAnt
if iscaleZAnt: tmpscaleZAnt=1/iscaleZAnt
bpy.ops.transform.resize(value=(tmpscaleXAnt, tmpscaleYAnt, \
tmpscaleZAnt ), constraint_axis=(False, False, False), \
orient_type='GLOBAL', mirror=False, \
proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
proportional_size=1, snap=False, snap_target='CLOSEST', \
snap_point=(0, 0, 0), snap_align=False, \
snap_normal=(0, 0, 0), release_confirm=False)
iscaleX=iscaleY=iscaleZ=0
if bEscalaX: iscaleX = ival*iEscalaXneg+iMinScaleBaseX
if bEscalaY: iscaleY = ival*iEscalaYneg+iMinScaleBaseY
if bEscalaZ: iscaleZ = ival*iEscalaZneg+iMinScaleBaseZ
bpy.ops.transform.resize(value=(iscaleX, iscaleY, \
iscaleZ), constraint_axis=(False, False, False), \
orient_type='GLOBAL', mirror=False, \
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
proportional='DISABLED', proportional_edit_falloff='SMOOTH', \
proportional_size=1, snap=False, \
snap_target='CLOSEST', snap_point=(0, 0, 0), \
snap_align=False, snap_normal=(0, 0, 0), \
release_confirm=False)
iscaleXAnt= iscaleX
iscaleYAnt= iscaleY
iscaleZAnt= iscaleZ
if bRotacao:
if iRotateValAnt!=0:
bpy.context.active_object.rotation_euler= ((iRotateValAnt*-1)+ iRotationAxisBaseX) *bRotationX , \
((iRotateValAnt*-1)+ iRotationAxisBaseY) *bRotationY , \
((iRotateValAnt*-1)+ iRotationAxisBaseZ) *bRotationZ
bpy.context.active_object.rotation_euler= ((ival*iRotationNeg)+ iRotationAxisBaseX) * bRotationX, \
((ival*iRotationNeg)+ iRotationAxisBaseY) * bRotationY, \
((ival*iRotationNeg)+ iRotationAxisBaseZ) * bRotationZ
iRotateValAnt= ival*iRotationNeg
ob = bpy.context.active_object
if bEixo:
ob.keyframe_insert(data_path="location")
if bRotacao:
ob.keyframe_insert(data_path="rotation_euler")
if bEscala:
ob.keyframe_insert(data_path="scale")
print("Importing Blender Frame: "+str(i+obi.RunFrom+1)+"\tof "+str(len(array)-1) + "\tValue: "+ str(ival))
obi.iSumImportFrames+=1
# Fim do ELSE otimizador
# Fim bNaoValorIgual
if obi.RunFrom>= tot:
bpy.context.scene.frame_current = 1
context.object.imp_sound_to_anim.Info_Import="Done. Imported " + str(obi.iSumImportFrames) + " Frames"
from time import strftime
print('')
print("================================================================")
print("Imported: " +str(obi.iSumImportFrames) + " Key Frames")
print("Optimizer Pass 1 prepared to optimize: " +str(obi.iSumOptimizerP1) + " blocks of Frames")
print("Optimizer Pass 2 has optimized: " +str(obi.iSumOptimizerP2) + " Frames")
print("Optimizer Pass 3 has optimized: " +str(obi.iSumOptimizerP3) + " Frames")
print("Optimizer has optimized: " +str(obi.iSumOptimizerP1 + obi.iSumOptimizerP2 + obi.iSumOptimizerP3) + " Frames")
print(strftime("End Import: %H:%M:%S - by Vlassius"))
print("================================================================")
print('')
obi.RunFrom=0
obi.iSumImportFrames=0
obi.iSumOptimizerP1=0
obi.iSumOptimizerP2=0
obi.iSumOptimizerP3=0
return obi.RunFrom
else:
obi.RunFrom+= loop
context.object.imp_sound_to_anim.Info_Import="Processing Frame " + str(obi.RunFrom+loop) + \
" of " + str(tot-1) + " Frames"
return obi.RunFrom
context.object.imp_sound_to_anim.Working= "wavimport"
def invoke(self, context, event):
self.execute(context)
#==================================================================================================
# Button - Sound Process
#==================================================================================================
#
class OBJECT_OT_Botao_Go(bpy.types.Operator):
''''''
bl_idname = "import.sound_animation_botao_go"
# change in API
bl_description = "Process a .wav file, take movement from the sound and import to the scene as Key"
bl_label = "Process Wav"
filter_glob: StringProperty(default="*.wav", options={'HIDDEN'})
path: StringProperty(name="File Path", description="Filepath used for importing the WAV file", \
filename: StringProperty(name="File Name", description="Name of the file")
directory: StringProperty(name="Directory", description="Directory of the file")
def SoundConv(File, DivSens, Sensibil, Resol, context, bAutoSense, bRemoveBeat, bUseBeat, bMoreSensible, \
bLessSensible, AudioChannel, loop):
obg= OBJECT_OT_Botao_Go
#reseta contadores caso seja pedido
if context.object.imp_sound_to_anim.timer_reset_func:
context.object.imp_sound_to_anim.timer_reset_func=False
#abre arquivo se primeira rodada
if obg.RunFrom==0:
try:
obg.Wave_read= wave.open(File, 'rb')
except IOError as e:
print("File Open Error: ", e)