From BlenderWiki

Jump to: navigation, search
Blender3D FreeTip.gif
IMPORTANT! Do not update this page!
We have moved the Blender User Manual to a new location. Please do not update this page, as it will be locked soon.

Um exemplo de Script Python funcional

Agora que você sabe que o Blender é extensível a partir de Scripts Python e que possui as noções básicas de manuseamento de Scripts e como rodá-los, antes de explodir a sua cabeça com a referência completa da API do Blender para a linguagem Python, vamos dar uma olhada em um exemplo de Script Python funcional.

Nós vamos apresentar um pequeno Script para a produção de polígonos. Isso na verdade duplica mais ou menos o que a caixa de ferramentas de adicionar Objetos faz, você já a conhece e ela está acessível através do atalho Space → Add → Mesh → Circle, mas nesse caso, o Script irá criar polígonos “preenchidos” , e não somente o seu contorno.

Para tornar o Script mais simples, mas ainda completo, iremos exibir neste exemplo uma "Gaphic User Interface" (Interface Gráfica Usuário) (GUI) escrita usando completamente a API so Blender.

Cabeçalhos,importação de Módulos e Variáveis Globais

As primeiras 32 linhas de código estão listadas abaixo:

"Script header" (Cabeçalho do Script)

Manter a informação de partes do Manual ”No estado”
Como esta parte do Manual explica procedimentos avançados do Blender através de configuração e programação Interna, decidi manter os Scripts sem tradução parcial ou completa, incluindo os seus comentários. É desejável que o leitor que se aventure na área de programação possua um mínimo de conhecimento do Inglês para que possa se guiar através de manuais de programação, e para que possa compreender os comandos de maneira adequada
→ Ivan Paulos Tomé - Greylica


  1. ######################################################
  2. #
  3. # Demo Script for Blender 2.3 Guide
  4. #
  5. ###################################################S68
  6. # This script generates polygons. It is quite useless
  7. # since you can do polygons with ADD->Mesh->Circle
  8. # but it is a nice complete script example, and the
  9. # polygons are 'filled'
  10. ######################################################
  11.  
  12. ######################################################
  13. # Importing modules
  14. ######################################################
  15.  
  16. import Blender
  17. from Blender import NMesh
  18. from Blender.BGL import *
  19. from Blender.Draw import *
  20.  
  21. import math
  22. from math import *
  23.  
  24. # Polygon Parameters
  25. T_NumberOfSides = Create(3)
  26. T_Radius = Create(1.0)
  27.  
  28. # Events
  29. EVENT_NOEVENT = 1
  30. EVENT_DRAW = 2
  31. EVENT_EXIT = 3

Depois dos comentários necessários com a descrição daquilo que o Script faz, existem linhas ([016-022]) específicas para a importação dos Módulos Python. O código Blender significa a importação do módulo principal da API Python do Blender. NMesh é o módulo que provê acesso as Malhas do Blender, enquanto o código BGL e Draw dão acesso as constantes OpenGL e funções, bem como a Interface de Janelas do Blender, respectivamente.

O módulo math é o módulo matemático do Python, mas pelo fato de ambos os módulos math e os serem construídos com o Blender e estarem embutidos na instalação, você não necessitará uma instalação completa do Python para rodar este Script e fazer isto !

Os polígonos são definidos pelo número de lados que eles possuem e o seu raio. Estes parâmetros posuem valores que deverão ser definidos pelo usuário através da Interface Gráfica (GUI), portanto as linhas [025-026] criam dois Objetos do tipo “botões genéricos” , com o seu valor inicial padrão.

Finalmente, os Objetos da Interface de Usuário trabalham com, e geram eventos. O Identificados do evento (ou ID do evento, para abreviar) são números inteiros deixados pelo programador para que os usuários os definam. (eles todos podem ser diferente, a menos que hajam necessidades especiais!). É usualmente uma boa prática definir nomes mneumônicos para eventos, conforme foi feito aqui nas linhas [029-031].

Desenhando a Interface de Usuário (GUI)

O código que é responsável pelo desenho ou redesenho da GUI deverá residor dentro de uma função chamada draw (GUI drawing).

"GUI drawing" (Desenho da GUI)

  1. ######################################################
  2. # GUI drawing
  3. ######################################################
  4. def draw():
  5.         global T_NumberOfSides
  6.         global T_Radius
  7.         global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT
  8.  
  9.         ########## Titles
  10.         glClear(GL_COLOR_BUFFER_BIT)
  11.         glRasterPos2d(8, 103)
  12.         Text("Demo Polygon Script")
  13.  
  14.         ######### Parameters GUI Buttons
  15.         glRasterPos2d(8, 83)
  16.         Text("Parameters:")
  17.         T_NumberOfSides = Number("No. of sides: ", EVENT_NOEVENT, 10, 55, 210, 18,
  18.                 T_NumberOfSides.val, 3, 20, "Number of sides of out polygon");
  19.         T_Radius = Slider("Radius: ", EVENT_NOEVENT, 10, 35, 210, 18,
  20.                 T_Radius.val, 0.001, 20.0, 1, "Radius of the polygon");
  21.  
  22.         ######### Draw and Exit Buttons
  23.         Button("Draw",EVENT_DRAW , 10, 10, 80, 18)
  24.         Button("Exit",EVENT_EXIT , 140, 10, 80, 18)

As linhas [037-039] simplesmente garantem acesso aos dados Globais. A Coisa realmente interessante inicia nas linhas [042-044]. A Janela OpenGL é inicalizada, e a posição corrente é configurada para a posição (x=8, y=103). A origem desta referência é o canto mais baixo a esquerda da Janela de Script. Quando o título “Demo Polygon Script” é impresso. Uma "string" (amarração) ( aqui, string se refere á uma variável (em geral texto) de amarração dos códigos) mais á frente é escrita nas linhas ([047-048]).

Então os botões de entrada para os parâmetros são criados. O primeiro (linhas [049-050]) é um "NumButton" (Botão Numérico), exatamente como os Botões existentes em diversas Janelas do Blender. Para os significado de todos os parâmetros, por favor, refira-se a referência de API do Blender. Basicamente, existe um rótulo para o botão (label), o evento gerado pelo botão, a sua localização (x,y) e suas dimensões (comprimento, altura), seu valor, que são dados pertencentes ao Objeto do botão em si, e os valores máximo e mínimos permitidos, juntamente com um "text string" (texto de amarração) que irá aparecer como uma ajuda enquanto o usuário foca no valor do botão, como uma "tooltip" (dica de ferramenta). As linhas [051-052] definem um "Num Button" (Botão Numérico) com um "Slider" (Deslizador), com uma sintaxe muito similar. As linhas [055-056] finalmente criam um botão chamado Draw que irá criar o polígono e um botão de saída chamado Exit .

Manuseando eventos.

A Janela de Interface de Usuário (GUI) não será desenhada, e não irá funcionar, até que um manipulador de evento apropriado seja escrito e registrado (Handling events).

"Handling events" (Manuseando Eventos)

  1. def event(evt, val):
  2.         if (evt == QKEY and not val):
  3.                 Exit()
  4.  
  5. def bevent(evt):
  6.         global T_NumberOfSides
  7.         global T_Radius
  8.         global EVENT_NOEVENT,EVENT_DRAW,EVENT_EXIT
  9.  
  10.         ######### Manages GUI events
  11.         if (evt == EVENT_EXIT):
  12.                 Exit()
  13.         elif (evt== EVENT_DRAW):
  14.                 Polygon(T_NumberOfSides.val, T_Radius.val)
  15.                 Blender.Redraw()
  16.  
  17. Register(draw, event, bevent)

As linhas [058-060] definem o manipulador de eventos pelo teclado, aqui respondendo pelo atalho Q com uma chamada direta de código de saída Exit().

Mais interessantes são as linhas [062-072], responsáveis por manipular os eventos da Interface de Usuário (GUI). Cada vez que um botão da GUI é utilizado esta função é chamada, com o número de evento definido dentro do botão como parâmetro. O núcleo desta função é portanto uma estrutura de “seleção” do tipo "if/elif" (se/caso se) executando diferentes códigod de acordo com o número do evento.

Como última chamada, a função Register() é invocada. Isso efetivamente desenha a GUI e inicia o ciclo de captura de eventos (“event loop”).

Manipulação de Malhas

Finalmente, os códigos presentes em Main function mostram a função principal, aquela que cria efetivamente o polígono. Ela é relativamente uma simples edição de Malha, mas mostra muitos pontos importantes da estrutura interna do Blender.

"Main function" (Função Principal)

  1. ######################################################
  2. # Main Body
  3. ######################################################
  4. def Polygon(NumberOfSides,Radius):
  5.  
  6.         ######### Creates a new mesh
  7.         poly = NMesh.GetRaw()
  8.  
  9.         ######### Populates it of vertices
  10.         for i in range(0,NumberOfSides):
  11.                 phi = 3.141592653589 * 2 * i / NumberOfSides
  12.                 x = Radius * cos(phi)
  13.                 y = Radius * sin(phi)
  14.                 z = 0
  15.  
  16.                 v = NMesh.Vert(x,y,z)
  17.                 poly.verts.append(v)
  18.  
  19.         ######### Adds a new vertex to the center
  20.         v = NMesh.Vert(0.,0.,0.)
  21.         poly.verts.append(v)
  22.  
  23.         ######### Connects the vertices to form faces
  24.         for i in range(0,NumberOfSides):
  25.                 f = NMesh.Face()
  26.                 f.v.append(poly.verts[i])
  27.                 f.v.append(poly.verts[(i+1)%NumberOfSides])
  28.                 f.v.append(poly.verts[NumberOfSides])
  29.                 poly.faces.append(f)
  30.  
  31.         ######### Creates a new Object with the new Mesh
  32.         polyObj = NMesh.PutRaw(poly)
  33.  
  34.         Blender.Redraw()

A primeira linha importante aqui é a de número [082]. Aqui há uma novo Objeto de Malha, onde poly é criado. O Objeto de Malha é constituído de uma lista de vértices e uma lista de faces, mais algumas coisas interessantes. Para a nossa finalidade, as listas de vértices e faces são o que precisamos.

Claro que a Malha criada recentemente é vazia. O primeiro ciclo (linhas [085-092]) computa a localização x,y,z do número de lados de NumberOfSides, incluindo os vértices necessários para definir o polígono. Sendo uma figura lisa ela terá o tamanho Z=0 para todos. A Linha [091] chama o método NMesh Vert() para criar um novo Objeto vértice a partir das coordenadas (x,y,z). Esse tipo de Objeto é então juntado/anexado (linha [092]) dentro da malha poly, na lista verts.

Finalmente (nas linhas [095-096]) um último vértice é adicionado no centro.

As linhas [099-104] agora conectam esses vértices para fazer faces. Não é requerido que sejam criados todos os vértices primeiramente e então as faces. Você pode seguramente criar uma nova face tão logo todos os vértices esteja ali.

A Linha [100] cria um novo Objeto Face. Um Objeto Face possui sua própria lista de vértices v (até 4) pra definí-lo.

As linhas [101-103] anexam/juntam três vértices para a lista original vazia f.v. Os vértices são dois vértices subsequentes do polígono e o vértice central. Estes vértices deverão ser pegos a partir da lista verts da Malha.

Finalmente, a linha [104] anexa/junta as faces recém criadas para a lista faces de nossa Malha poly.

Conclusões

A Interface GUI de nosso exemplo.
O resultado de nosso Script de exemplo.

Caso você crie um arquivo chamado polygon.py contendo o código acima especificado e o carregue dentro da Janela de texto do Blender, conforme você aprendeu nas páginas anteriores, e pressione a combinação AltP nesta janela para rodr o Script, você verá o Script desaparecendo e a Janela se tornando Cinza. No canto esquerdo de baixo, uma GUI será então desenhada (A Interface GUI de nosso exemplo.).

Pela seleção, por exemplo, 5 vértices e um raio de 0.5, e pressionando o botão Draw, um pentágono irá aparecer no plano XY da Janela de Visualização 3D (O resultado de nosso Script de exemplo.).