Aprender pode ser uma experiência deliciosa, principalmente quando o desafio envolvido nos instiga a ir além. Para apimentar, podemos desbravar esse continente didático de formas pouco convencionais, ou seja, pirando na batatinha!
Que área melhor para efetivar isso que a da programação? Pois é, uma mistura explosiva para essa brincadeira são dois elementos já por natureza superinteressantes: o Blender 3D e a linguagem Python.
1. Conhecimentos prévios
Para quem não conhece o Blender é um editor 3D. Ou seja, ele serve para fazer objetos e cenas tridimensionais, mas não apenas isso, entre outras coisas pode-se usá-lo para criar curta-metragens animados, efeitos visuais, edição de vídeo, maquetes eletrônicas e até jogos! Usaremos uma característica interessante para divertirmo-nos: o Blender permite que criemos scripts através da linguagem Python.
Podemos acessar todas as suas funcionalidades por ela, não é um barato!
Se você deseja colocar em prática os ensinamentos contidos nesse material, deverá ter conhecimentos básicos de Blender. Se nunca ouviu falar no próprio ou nunca aventurou-se a usá-lo, uma boa oportunidade é ler a apostila básica gratuita que desenvolvi a quem posso interessar, clicando aqui.
2. O que vamos fazer
1. Coletar os dados de um objeto na cena;
2. Jogar esses dados num arquivo de texto simples;
3. Postar esse arquivo num site usando ftp (você vai precisar de um site pessoal que permita essa operação);
4. Abrir o arquivo remoto utilizando o Firefox.
Tudo dentro do Blender e via script!
3. Configurando a área de trabalho
Para esse tutorial, o Linux Fedora 8 foi escolhido como sistema operacional, mas relaxe, pois o Blender roda em todos os sistema operacionais mais conhecidos no mercado. Seja Linux, Windows, MacOSX, Irix e cia. ltda. ele rodará tranquilamente.
Vamos abrir um terminal e chamar o Blender pelo comando:
Lembrando que o $ não deve ser digitado, ele serve apenas como referência para mostrar que estamos trabalhando no console.
Assim que abrir o Blender, redimensione ele de modo que divida espaço com o terminal e depois divida a área de trabalho em duas.
Em seguida vá na janela da direita e selecione Text Editor.
Em seguida, mova o mouse sobre a janela a direita e pressione ALT+N, assim criamos um novo arquivo para ser editado.
Prontinho, temos um editor de texto aberto, basta digitarmos os comandos nele em Python que a coisa funcionará conforme o solicitado. Vamos fazer um teste?
Digite o comando:
Vá em File –> Run Python Script
Obs.: Da próxima ver que você for rodar o script, basta mover a seta do mouse sobre o editor de texto e pressionar ALT+P, como aparece no menu acima.
Volte a sua atenção para o terminal e veja que a impressão apareceu logo abaixo da mensagem de inicialização do Blender.
O que aconteceu? Nós rodamos o Python dentro do Blender!
Para ativar a coloração de sintaxe do editor de texto basta clicar no botão que aparece acima.
Se quiser salvar o arquivo vá em File –> Save e salve com a extensão .py.
Agora você está apto a seguir adiante.
4. É hora de diversão!
Chegou a hora de montar o script, mas não pense que iremos direto ao ponto. Refestele-se em sua poltrona e vamos deliciarmo-nos ao digerir as possibilidades que essa dupla do barulho (Blender e Python) nos oferece.
4.1. Coletando os dados de um objeto selecionado
Nós temos vários objetos na cena padrão do Blender…
Como vemos aí, um Cube, uma Lamp e uma Camera.
Precisamos de um comando que liste os objetos na cena, para então selecionarmos um deles.
Conseguiremos isso com:
O seguinte:
obj = Blender.Object.Get()
print obj
Pelo qual teremos essa saída no terminal:
Mas o que significa o comando? Vamos estudá-lo a la Jack, o Estripador… por partes…
Aqui importamos o módulo que permite ao Python comunicar-se com o Blender.
Depois atribuíamos à variável obj uma lista com os objetos que a cena contém.
Perceba os pontos separando os objetos… primeiro temos o Blender, seguido de Object e por fim Get().
Dentro do módulo Blender, encontra-se simplesmente tudo que consta no programa. Nesse caso nós escolhemos Object, mas poderia ser Scene, Curve, Render e uma infinidade de opções como podemos atestar aqui.
Uma vez dentro do submódulo Object, temos ainda outras opções, como New() que cria um novo objeto, GetSelected() que pega o objeto selecionado, entre outras. No nosso caso selecionamos o Get() por que ele pega os objetos da cena e joga tudo numa lista.
Para podermos ver o que tem dentro da variável obj é necessário que imprimamos ela na tela. Taí o por que do comandinho final.
Agora vamos pensar um pouco. O intuito dessa primeira etapa é selecionarmos um dos objetos da cena e fazer extrair os dados dele. Isolando em partes:
2. Extrair dados.
Vamos efetivar o primeiro objetivo. Dentro os três que vimos na saída:
Selecionaremos um deles… mas como?
Bem, não citei a pouco que essa saída tratava-se de uma lista? Pois bem, podemos isolar os elemtos dela, simplesmente colocando o número dele depois do código…
obj = Blender.Object.Get()[0]
print obj
Rodando o comando temos a seguinte saída:
Mas por que isso aconteceu? Simples, a resposta está no [0] depois do Get(). O primeiro elemento da lista é a Camera, e seu número no índice é 0. Se quisermos ver o segundo elemento basta trocarmos o 0 pelo 1:
obj = Blender.Object.Get()[1]print obj
Logo, teremos a saída:
Entendidos? Brinque um pouco com essa possilidade antes de passarmos para o segundo objetivo. Lembra? O esquema aqui é degustar o que se aprende.
Agora vamos extrair os dados de um objeto na cena. Por convensão decidi escolher um sólido, nesse caso o Cube. Se olharmos na figura acima veremos que trata-se do Blender.Object.Get()[1].
Os dados que serão extraídos:
2. Localização (coordenadas);
3. Tipo de visualização do objeto.
4.1.1. Extraindo o nome do objeto
Vamos alterar levemente o código do script.
obj = Blender.Object.Get()[1]obj_name = obj.getName()
print obj_name
Obs.: Perceba que o print foi alterado para que a saída do comando seja apenas os dados da nossa nova variável, a obj_name.
Logo, teremos a saída:
Pequena no tamanho, mas grande na eficiência, era isso mesmo que precisávamos!
Aqui pegamos os dados da seleção do objeto, o obj e isolamos apenas o seu nome atravéz do getName().
Por fim mandamos imprimir os dados contidos na variável, o que oferecerá apenas o nome do objeto, ou seja, Cube.
4.1.2. Extraindo a localização do objeto
Novamente mais um incremento no código.
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
print obj_loc
Obs.: Perceba que o print foi alterado para que a saída do comando seja apenas os dados da nossa nova variável, a obj_loc.
O nosso querido getLocation() funciona da mesma forma que o anterior… a saída:
4.1.3. Extraindo o tipo de visualização do objeto
Com esse comando, vamos ver o tipo de visualização do objeto. O que vem a ser isso? Vamos ver o resultado, depois explico o significado.
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_mod = obj.getDrawType()
print obj_mod
Obs.: Perceba que o print foi alterado para que a saída do comando seja apenas os dados da nossa nova variável, a obj_mod.
Quando vemos a saída, temos o seguinte resultado:
4? Mas quatro o que? Simples… veja o gráfico abaixo:
Esse é o mesmo objeto com modos de visualização diferenciados. O tipo padrão é o Shaded, taí o motivo do 4 ter aparecido! Mas não selecionei o getDrawType() à toa. Nós não vamos imprimir um 4 em nosso arquivo de saída e sim o tipo de visualização, nesse caso o Shaded. Mas para isso teremos que rebuscar um pouco o nosso código…
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
print obj_mod_str
Aqui criamos uma estruturas de ifs e elifs que vão testar um por um dos tipos até achar o que é coerente com o do objeto e por fim imprimí-lo na tela:
4.2. Jogando os dados coletados num arquivo de texto
Antes de tudo, vamos entender como criar um arquivo de texto no Python. A forma geral é a seguinte:
2. Escreve-se no arquivo;
3. Fecha-se o arquivo.
Num exemplo em código ficaria assim:
arquivo.write(“Escrevendo no arquivo.”)
arquivo.close()
Simples não? Só três passos… criar, escrever e fechar.
Vamos transportar essa idéia para o nosso script:
# Coleta dados
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
# Escreve dados num arquivo de texto
arquivo = file(‘/tmp/arquivo_dados.txt’, ‘w’)
arquivo.write(obj_name)
arquivo.write(obj_loc)
arquivo.write(obj_mod_str)
arquivo.close()
Tudo certinho, vamos rodar e ver o que acontece:
File “Text.001”, line 27, in <module>
TypeError: argument 1 must be string or read-only character buffer, not tuple
Uia! O que é isso?
Bem, vamos analisar… ele diz que o problema está na linha 27:
mos transportar essa idéia para o nosso script:
No TypeError ele diz que não pode ser uma tupla, então, temos que fazer uma conversão de tupla para… bem, como estou nos rudimentos da programação a saída que achei foi converter para uma string. De olho para uma pequena alteração no código:
# Coleta dados
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_loc_str = str(obj_loc)
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
# Escreve dados num arquivo de texto
arquivo = file(‘/tmp/arquivo_dados.txt’, ‘w’)
arquivo.write(obj_name)
arquivo.write(obj_loc_str)
arquivo.write(obj_mod_str)
arquivo.close()
Com a função str() convertermos a tupla numa string, ou, num texto formado por números.
Vamos rodar o script e depois abrir o resultado em /tmp/arquivo_dados.txt usando um editor de texto.
É… deu certo mas ainda não está agradável aos olhos. Os dados estão concatenados (tudo grudado!). Seria legal se colocassemos os resultados em linhas diferentes e é o que faremos. De olho no código:
# Coleta dados
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_loc_str = str(obj_loc)
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
# Escreve dados num arquivo de texto
arquivo = file(‘/tmp/arquivo_dados.txt’, ‘w’)
arquivo.write(obj_name)
arquivo.write(“n”)
arquivo.write(obj_loc_str)
arquivo.write(“n”)
arquivo.write(obj_mod_str)
arquivo.close()
O segredinho é inserir um caractere de nova linha n onde for necessário.
Prontinho, nosso arquivo está criado!
4.3. Mandando o arquivo para a internet
Até agora só não achei um módulo que fizesse chover, de resto o Python tem pra tudo!
Um belo dia me deparei com o ftplib e foi amor a primeira vista. Trago um pouco dessa paixão aqui para você nobre leitor, nesse próximo passo.
2. Atribui os dados de conexão a uma variável;
3. Abre o arquivo que será enviado atribuindo-o a uma variável;
4. Envia o arquivo;
5. Fecha o arquivo;
6. Encerra a conexão.
Algo nesse sentido:
con = FTP(‘ftp.endereco.com.br’,’nome_usuario’,’senha’)
arquivo_envia = open(‘/tmp/arquivo_dados.txt’,’rb’)
con.storbinary(‘STOR arquivo_dados.txt’, arquivo_envia)
arquivo_envia.close()
con.quit()
Vamos destrinchar o código…
Primeiro importamos o submódulo FTP do ftplib.
Depois atribuímos à con variável com os dados de conexão… imaginemos que no teu caso os dados fossem esses:
Usuário: hombrecito
Senha: bagualdemais
Ficaria como aparece acima…
Aqui abrimos o arquivo arquivo_dados.txt, aquele que criamos no passo anterior e atribuímos ele à variável arquvo_envia.
Em seguida, usamos os dados contidos na variável con para fazer a operação de upload (storbinary()) ou envio do arquivo arquivo_dados.txt, cujos dados estão contidos na variável arquivo_envia.
Fechamos o arquivo.
Fechamos a conexão.
Vamos tranferir o que aprendemos para o nosso script:
from ftplib import FTP
# Coleta dados
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_loc_str = str(obj_loc)
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
# Escreve dados num arquivo de texto
arquivo = file(‘/tmp/arquivo_dados.txt’, ‘w’)
arquivo.write(obj_name)
arquivo.write(“n”)
arquivo.write(obj_loc_str)
arquivo.write(“n”)
arquivo.write(obj_mod_str)
arquivo.close()
# Envia dados para a internet
con = FTP(‘teste.com.br’,’hombrecito’,’bagualdemais’)
arquivo_envia = open(‘/tmp/arquivo_dados.txt’,’rb’)
con.storbinary(‘STOR arquivo_dados.txt’, arquivo_envia)
arquivo_envia.close()
con.quit()
Rodamos o script e se tudo correr bem, basta abrir o Firefox e entrar no endereço corresposdente ao site enviado:
Certinho! Isso nos permite dar o próximo passo.
4.4. Abrindo o Firefox com o endereço remoto
Para fechar com chave de ouro vamos terminar o script acessando os comandos do sistema operacional como se estivessemos no console, mas via Python. Para tal lançaremos mão do módulo os. Com ele nós chamaremos o navegador de internet e de quebra já setaremos a URL que ele abrirá.
from ftplib import FTP
import os
# Coleta dados
obj = Blender.Object.Get()[1] obj_name = obj.getName()
obj_loc = obj.getLocation()
obj_loc_str = str(obj_loc)
obj_mod = obj.getDrawType()
if obj_mod == 1:
obj_mod_str = “Bounding box”
elif obj_mod == 2:
obj_mod_str = “Wire”
elif obj_mod == 3:
obj_mod_str = “Solid”
elif obj_mod == 4:
obj_mod_str = “Shaded”
elif obj_mod == 5:
obj_mod_str = “Textured”
# Escreve dados num arquivo de texto
arquivo = file(‘/tmp/arquivo_dados.txt’, ‘w’)
arquivo.write(obj_name)
arquivo.write(“n”)
arquivo.write(obj_loc_str)
arquivo.write(“n”)
arquivo.write(obj_mod_str)
arquivo.close()
# Envia dados para a internet
con = FTP(‘teste.com.br’,’hombrecito’,’bagualdemais’)
arquivo_envia = open(‘/tmp/arquivo_dados.txt’,’rb’)
con.storbinary(‘STOR arquivo_dados.txt’, arquivo_envia)
arquivo_envia.close()
con.quit()
# Abre o Firefox no endereco do arquivo na internet
os.popen(‘firefox http://cogitas3d.procedural.com.br/arquivo_dados.txt’)
Agora é só rodar e correr pro abraço!
5. Conclusão
O que é bom dura pouco, mas nem tudo. No caso da programação podemos estender o nosso prazer didático por um tempo indeterminado. Isso por que sempre podemos melhorar o que criamos, sem contar que ainda temos um mar de novos recursos a explorar.
Programar não é apenas criar novos códigos, mas ajudar no desenvolvimento do que já existe, ou mesmo testar os de terceiros. Nesse caso, não é apenas didático, mas nobre.
Então fique esperto, a coisa não termina por aqui. A API de script do Blender é riquíssima e tem um monte de recursos te esperando para serem descobertos e deliciados. Comece agora mesmo a explorá-los!
Sucesso nessa busca e grande abraço.
Cícero Moraes.
Deixe seu comentário