Blender Dokumentation: Ein Beispielscript in Python

Aus Wikibooks
Wechseln zu: Navigation, Suche
<<<Zurück
Python in Blender
Inhaltsverzeichnis

Handbuch durchsuchen

Weiter>>>
Mitgelieferte Scripte


Diese Seite bezieht sich auf Blender v2.42a


Ein Beispiel in Python[Bearbeiten]

Nun wissen Sie, dass Blender mit Python erweiterbar ist, wie man damit umgeht und ein Script ausführt. Bevor Sie Ihrem Gehirn nun die volle Breitseite mit der Python API Referenz geben, wollen wir uns erst ein kleines Beispiel zu Gemüte führen.

Wir bauen uns ein kleines Script, welches Polygone erzeugt. Das macht zwar so ziemlich das Gleiche wie die Space>>Add>>Mesh>>Circle Toolboxoption, es erzeugt aber 'gefüllte' Polygone - nicht nur die Aussenlinie.

Um das Script schön einfach bedienbar zu machen, spendieren wir ihm eine Benutzerschnittstelle (GUI), welche wir komplett mit der Blender API erzeugen.

Headers, Import von Modulen und globale Variablen[Bearbeiten]

Hier kommen die ersten 32 Zeilen des Scripts

Script Header

 1  ######################################################
 2  #
 3  # Demo Script für das Blender Handbuch
 4  #
 5  ######################################################
 6  # Diese Script erzeugt Polygone. Funktionell ist es 
 7  # überflüssig, da gefüllte Polygone mit  
 8  # ADD->Mesh->Circle erzeugt werden können. Aber es 
 9  # ist ein schönes, komplettes Beispielscript.
10  ######################################################
11  
12  ######################################################
13  # Import der Module
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


Zuerst kommt der Kommentar mit der Erklärung, was das Script macht. In den Zeilen 016-022 importieren wir die Pythonmodule:

  • Blender ist das Blender-Python API Hauptmodul
  • NMesh ist das Modul welches den Zugriff auf Blenders Meshes unterstützt,
  • BGL gibt Zugriff auf die OpenGL Funktionen
  • Draw gibt Zugriff auf Blenders Fensterschnittstelle
  • Das math Modul ist, wie unschwer zu erraten, Pythons Mathemodul.


Blender3D FreeTip.gif

Wenn Sie Python nicht komplett installiert haben oder nicht wollen, dann ändern Sie die Zeilen
021 import math
022 from math import *
in
021 from Blender import Mathutils
022 from Blender.Mathutils import *



Die Polygone werden durch die Anzahl ihrer Seiten und ihren Radius definiert. Die Werte dieser Parameter werden durch den Benutzer über die GUI eingegeben. In den Zeilen 025-026 erzeugen wir zwei Generic Button Objekte mit ihren Startwerten.

Intern erzeugen die GUI-Objekte Events. Events IDs [Events identifier] sind Integer, die der Programmierer definiert. Es hat sich als sinnvoll erwiesen, den Events Mnemonic Namen zu geben, wie es hier in den Zeilen 029-031 gemacht wurde.

Zeichnen der GUI[Bearbeiten]

Der Code, der für das Zeichnen der GUI verantwortlich ist, wird in eine draw Funktion geschrieben.

33  ######################################################
34  # Zeichnen der GUI
35  ######################################################
36  def draw():
37  	global T_NumberOfSides
38  	global T_Radius
39  	global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT
40  
41  	########## Titel
42  	glClear(GL_COLOR_BUFFER_BIT)
43  	glRasterPos2d(8, 103)
44  	Text('Demo Polygon Script')
45  
46  	######### Die Parameter der GUI Buttons
47  	glRasterPos2d(8, 83)
48  	Text("Parameter:")
49  	T_NumberOfSides = Number('Anz. Seiten: ', EVENT_NOEVENT, 10, 55, 210, 18,
50                      T_NumberOfSides.val, 3, 20, 'Anzahl der Polygonaussenkanten');
51  	T_Radius        = Slider('Radius: ', EVENT_NOEVENT, 10, 35, 210, 18,
52                      T_Radius.val, 0.001, 20.0, 1, 'Radius des Polygons');
53  
54  	######### Zeichnen- und Exitbuttons
55  	Button('Zeichnen',EVENT_DRAW , 10, 10, 80, 18)
56  	Button('Exit',EVENT_EXIT , 140, 10, 80, 18)

Die Zeilen 037-039 gewähren lediglich Zugriff auf globale Daten. Wirklich interessant wird es erst ab den Zeilen 042-044. Hier wird das OpenGL Fenster initialisiert und auf die Position X=8 und Y=103 gesetzt. Dabei wird die linke untere Ecke des Scriptfensters als Ausgangspunkt angenommen. Dort wird der Titel Demo Polygon Script ausgegeben.

Unter dem String Parameter: (Zeilen 047-048) werden die Buttons für die Parameter erzeugt. Der Erste ist ein Number Buttom (Zeile 049-050), wie er in den verschiedenen Buttons Fenstern von Blender zu finden ist. Grundsätzliche Parameter sind:

  • der Buttonname (das was draufsteht)
  • das Event, welches durch den Button ausgelöst wird
  • die Position (x,y), die Größe (Höhe, Breite)
  • der Initialwert
  • der minimal und maximal mögliche Wert
  • einen String, welcher als Tooltip erscheint, wenn Sie mit der Maus darüberfahren.


Blender3D FreeTip.gif

Schauen Sie bitte in die API-Referenz für mehr Informationen über die Parameter.



In den Zeilen 051-052 wird ein Number Button mit einem Slider definiert. Die Zeilen 055-056 erzeugen einen Klickbutton mit dem Titel 'Zeichnen', welcher das Polygon generiert, und einen Exit Button.

Eventbehandlung[Bearbeiten]

Die GUI wird nicht ohne den dazugehörigen und registrierten Eventhandler gezeichnet.

58  def event(evt, val):	
59  	if (evt == QKEY and not val): 
60  		Exit()
61  
62  def bevent(evt):
63  	global T_NumberOfSides
64  	global T_Radius
65  	global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT
66  
67  	######### GUI Events behandeln
68  	if (evt == EVENT_EXIT): 
69  		Exit()
70  	elif (evt== EVENT_DRAW):
71  		Polygon(T_NumberOfSides.val, T_Radius.val)
72   		Blender.Redraw()
73  
74  Register(draw, event, bevent)

In den Zeilen 058-060 wird ein Eventhandler für die Tastatur definiert, welcher auf das Drücken der Q-Taste mit dem Aufruf der Funktion Exit() reagiert und das Script verlässt.

Viel interessanter sind die Zeilen 062-072, da sie die GUI Events steuern. Diese Funktion wird jedes Mal aufgerufen, wenn ein GUI Button benutzt wird. Ihr wird die Eventnummer der Buttons als Parameter übergeben. Der Kern dieser Funktion ist daher eine "Switch" Struktur, die je nach Event verschiedenen Code ausführt.

Als letztes wird die Register Funktion aufgerufen. Sie zeichnet schlußendlich die GUI und startet eine Dauerschleife für die Eventerfassung.

Meshes[Bearbeiten]

Am Ende kommen wir noch zur Hauptfunktion [main function], die das Polygon erzeugt. Hier wird eigentlich einfach nur ein Mesh editiert, aber es offenbart eine Menge wichtiger Punkte der internen Datenstruktur von Blender.

 76  ######################################################
 77  # Hauptfunktion
 78  ######################################################
 79  def Polygon(NumberOfSides,Radius):
 80 
 81 	######### Erstellt ein neues Mesh
 82 	poly = NMesh.GetRaw()
 83 
 84 	######### Fügt Vertices zu dem Mesh hinzu 
 85 	for i in range(0,NumberOfSides):
 86 	  phi = 3.141592653589 * 2 * i / NumberOfSides
 87 	  x = Radius * cos(phi)
 88 	  y = Radius * sin(phi)
 89 	  z = 0
 90 
 91 	  v = NMesh.Vert(x,y,z)
 92 	  poly.verts.append(v)
 93 
 94 	######### Fügt einen neuen Vertex in die Mitte ein
 95 	v = NMesh.Vert(0.,0.,0.)
 96 	poly.verts.append(v)
 97 
 98 	######### Verbindet die Vertices zu einem Face
 99 	for i in range(0,NumberOfSides):
100 		f = NMesh.Face()
101 		f.v.append(poly.verts[i])
102 		f.v.append(poly.verts[(i+1)%NumberOfSides])
103 		f.v.append(poly.verts[NumberOfSides])
104 		poly.faces.append(f)
105 
106 	######### Erstellt ein neues Objekt aus dem Mesh
107 	polyObj = NMesh.PutRaw(poly)
108 
109 	Blender.Redraw()

Die erste wichtige Zeile ist 082. Hier wird ein neues Meshobjekt namens poly erzeugt. Das Meshobjekt besteht aus einer Reihe Vertices und Faces, plus einigen anderen interessanten Sachen. Für unsere Zwecke reichen die Vertices und Faces aus.

Naturgemäß ist ein neues Mesh leer. Die erste Schleife in den Zeilen 085-092 errechnet die x,y,z Position der NumberOfSides Vertices, welche für das Erzeugen des Polygons nötig sind. Weil z=0 ist, ist das Polygon flach.

Die Zeile 091 ruft die Methode vert von NMesh auf, die ein neues Vertexobjekt mit den Koordinaten (x,y,z) erzeugt. Dieses Objekt wird dann in die verts' Liste des Meshobjekts poly hinzugefügt (Zeile 092).

Zum Schluss wird noch ein letztes Vertex in die Mitte eingefügt (Zeilen 095-096).

Die Zeilen 099-104 verbinden die Vertices um ein Face zu erstellen. Es ist nicht notwendig zuerst alle Vertices und dann die Faces zu erstellen. Ein neues Face kann erstellt werden, wenn alle seine Vertices erstellt sind.

Die Zeile 100 erzeugt ein neues Faceobjekt. Ein Faceobjekt bringt seine eigene, leere, Liste v (mehr als 4 Vertices) mit, wodurch es definiert wird. Die Zeilen 101-103 fügen der leeren Liste f.v 3 Vertices hinzu. Die Vertices sind 2 nachfolgende Vertices des Polygons und des zentralen Vertice. Diese Vertices müssen von der Meshliste verts genommen werden. Die letzte Zeile der Schleife 104 fügt das neu erzeugte Face der faces Liste unseres Meshobjektes poly hinzu.

Ergebnis[Bearbeiten]

Abbildung 2: Unsere erzeugte GUI

Erstellen Sie nun eine Datei polygon.py mit dem Code als Inhalt und laden Sie sie in Blenders Textfenster, wie es oben erklärt wurde. Drücken Sie nun Alt-P um das Script zu starten. Das Textfenster wird grau und in der linken unteren Ecke wird die GUI gezeichnet.


Wenn Sie nun, sagen wir mal, 5 Vertices und einen Radius von 0.5 einstellen und auf den Zeichnen Button drücken, erscheint eine XZ Ebene im 3D Fenster.

Abbildung 3: Unser erzeugtes Polygon


Scriptlisting[Bearbeiten]

Hier ist das Script ohne Zeilennummern:

import Blender
from Blender import NMesh
from Blender.BGL import *
from Blender.Draw import *

import math
from math import *

# Polygon Parameters
T_NumberOfSides = Create(3)
T_Radius        = Create(1.0)

# Events
EVENT_NOEVENT = 1
EVENT_DRAW    = 2
EVENT_EXIT    = 3

######################################################
# Zeichnen der GUI
######################################################
def draw():
    global T_NumberOfSides
    global T_Radius
    global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT

    ########## Titel
    glClear(GL_COLOR_BUFFER_BIT)
    glRasterPos2d(8, 103)
    Text('Demo Polygon Script')

    ######### Die Parameter der GUI Buttons
    glRasterPos2d(8, 83)
    Text("Parameter:")
    T_NumberOfSides = Number('Anz. Seiten: ', EVENT_NOEVENT, 10, 55, 210, 18,
                    T_NumberOfSides.val, 3, 20, 'Anzahl der Polygonaussenkanten');
    T_Radius        = Slider('Radius: ', EVENT_NOEVENT, 10, 35, 210, 18,
                    T_Radius.val, 0.001, 20.0, 1, 'Radius des Polygons');

    ######### Zeichnen- und Exitbuttons
    Button('Zeichnen',EVENT_DRAW , 10, 10, 80, 18)
    Button('Exit',EVENT_EXIT , 140, 10, 80, 18)

def event(evt, val):       
    if (evt == QKEY and not val):
            Exit()

def bevent(evt):
    global T_NumberOfSides
    global T_Radius
    global EVENT_NOEVENT, EVENT_DRAW, EVENT_EXIT

    ######### GUI Events behandeln
    if (evt == EVENT_EXIT):
            Exit()
    elif (evt== EVENT_DRAW):
            Polygon(T_NumberOfSides.val, T_Radius.val)
            Blender.Redraw()

Register(draw, event, bevent)

######################################################
# Main Body
######################################################
def Polygon(NumberOfSides,Radius):

    ######### Creates a new mesh
    poly = NMesh.GetRaw()

    ######### Populates it of vertices
    for i in range(0,NumberOfSides):
      phi = pi * 2 * i / NumberOfSides
      x = Radius * cos(phi)
      y = Radius * sin(phi)
      z = 0

      v = NMesh.Vert(x,y,z)
      poly.verts.append(v)

    ######### Adds a new vertex to the center
    v = NMesh.Vert(0.,0.,0.)
    poly.verts.append(v)

    ######### Connects the vertices to form faces
    for i in range(0,NumberOfSides):
            f = NMesh.Face()
            f.v.append(poly.verts[i])
            f.v.append(poly.verts[(i+1)%NumberOfSides])
            f.v.append(poly.verts[NumberOfSides])
            poly.faces.append(f)

    ######### Creates a new Object with the new Mesh
    polyObj = NMesh.PutRaw(poly)

    Blender.Redraw()


<<<Zurück

Python in Blender

Inhaltsverzeichnis
Glossar
Weiter>>>

Mitgelieferte Scripte