Contents
Allgemeines
Blender ist ein sehr umfangreiches 3D-Modelling-, Rendering- und Animationsprogramm. In Blender ist ein Python-Interpreter eingebettet, sodass man Blender sehr einfach mittels Python-Scripten erweitern kann. Die Python-API folgt dabei recht genau dem graphischen User-Interface von Blender. Wenn man Grundkenntnise in Python hat und weiß, wie man ein Ziel manuell in Blender erreichen kann, so ist es nicht schwer, dies in einem Script umzusetzen.
Allgemeines zur Benutzung von Blender findet sich im Blender-Manual. (Es gibt auch eine deutsche Übersetzung.) Daraus sei zum Schnuppern folgendes empfohlen:
Was man mit Blender alles anstellen kann, vermittelt das "Open Movie" Elephants Dream sehr gut.
Python-Scripte zum Laufen bekommen
Blender bringt zwar seinen eigenen Interpreter mit, aber um auf Pythons Standardbibliothek zugreifen zu können, wird eine vollständige Python-Installation benötigt. Es kann notwendig sein, Blender explizit mitzuteilen, wo sich die normale Python-Installation befindet, bzw. wo die Module gesucht werden müssen. Dazu muss die Umgebungsvariable PYTHONPATH gesetzt werden (s.u.). Zu beachten ist, dass Blender jeweils für verschiedene Python-Versionen angeboten wird. Passt die Blender-Version nicht zur Python-Version, kann es zu Problemem kommen.
PYTHONPATH setzen unter Windows
Man geht in der Systemsteuerung auf Sytem und wählt im Registerreiter Erweitert den Knopf Umgebungsvariablen. Mit Neu legt man eine neue Umgebungsvariable mit Namen PYTHONPATH. Als Wert trägt man ein C:\PYTHON24;C:\PYTHON24\DLLS;C:\PYTHON24\LIB;C:\PYTHON24\LIB\LIB-TK (je nachdem, wohin man Python installiert hat).
PYTHONPATH setzen unter Linux
In die Datei .bashrc z.B. folgendes eintragen:
export PYTHONPATH=/usr/local/lib/python2.4:/usr/local/lib/python2.4/plat-linux2:/usr/local/lib/python2.4/lib-tk:/usr/local/lib/python2.4/lib-dynload:/usr/local/lib/python2.0/site-packages
Welche Verzeichnisse genau eingetragen werden müssen, sagt einem sys.path der normalen Python-Installation:
1 import sys
2 print sys.path
Scripte aus Menüs heraus auführen
Blender bringt schon viele Python-Scripte mit, sie liegen im Installationsverzeichnis unter scripts. Man kann die Scripte in den verschiedensten Blender-Menüs finden, sie werden duch ein kleines Schlangen-Symbol gekennzeichnet. Welche Pfade für die Menüs durchsucht werden sollen, kann man im User Preferences-Fenster unter File Paths einstellen:
Scripte aus dem Text Editor heraus auführen
Um Scripte schnell zu testen, kann man sie in Blenders Text Editor laden (oder sie gleich im Text Editor schreiben). Im File-Menü gibt es einen Eintrag Run Python Script (Alt+p).
Objekte erzeugen
Im Folgenden wollen wir ein Viereck vom Typ Mesh-Objekt erstellen und ihm eine Textur hinzufügen.
Der Kopf eines Blender-Scriptes
So sieht der Anfang eines Blender-Scriptes aus:
1 #!BPY
2
3 """
4 Name: 'Viereck 1'
5 Blender: 242
6 Group: 'Add'
7 Tooltip: 'Viereck hinzufuegen.'
8 """
9
10 __author__ = "Rebecca Breu"
11 __url__ = ("blender", "elysiun")
12 __version__ = "31.01.2007"
13 __bpydoc__ = """Mein erstes Script"""
Keine dieser Zeilen ist notwendig, aber sie sind zumindest ganz nützlich. Der Docstring am Anfang wird von Blender speziell behandelt: Name gibt an, wie der Menüeintrag zu diesem Script heißen soll. Group gibt an, in welchem Menü das Script zu finden ist, und Tooltip gibt an, welcher Tooltip unter dem Mauszeiger zu sehen sein soll. Die eigentliche Dokumentation wird in der Variable __bpydoc__ gespeichert.
Ein leeres Mesh-Objekt
Wir beginnen damit, der aktuell ausgewählten Szene ein leeres Mesh-Objekt hinzuzufügen:
1 import Blender
2 from Blender import Object
3 from Blender import NMesh
4 from Blender import Scene
5
6 # Neues Mesh erzeugen:
7 viereck_mesh = NMesh.New()
8
9 # Neues Objekt vom Typ "Mesh" erzeugen und ihm das erzeugte Mesh zuordnen:
10 viereck_obj = Object.New("Mesh", "Viereck") # Parameter: Typ, Name
11 viereck_obj.link(viereck_mesh)
12
13 # Die aktuelle Szene holen und das erzeugte Objekt hinzufuegen:
14 current_scene = Scene.GetCurrent()
15 current_scene.link(viereck_obj)
16
17 Blender.Redraw()
Das letzte Redraw() sorgt dafür, dass Blender seinen Inhalt neu zeichnet und wir das leere Objekt sofort sehen. Das Objekt wird in den Koordinaten (0, 0, 0) eingefügt ist nur an seinem Schwerpunkt zu erkennen:
Eckpunkte und Flächen
Ein Mesh wird definiert durch Eckpunkte (Verteces), Kanten (Edges) und Flächen (Faces). Fügen wir zunächst die vier Eckpunkte hinzu:
1 viereck_mesh.verts.append(NMesh.Vert(-1, -1, 0))
2 viereck_mesh.verts.append(NMesh.Vert(-1, 1, 0))
3 viereck_mesh.verts.append(NMesh.Vert(1, 1, 0))
4 viereck_mesh.verts.append(NMesh.Vert(1, -1, 0))
Kanten oder Flächen haben wir damit noch nicht erzeugt, und beim Rendern ist dieses Objekt nach wie vor nicht zu sehen, da beim Rendern allein die Flächen zählen!
Nun werden die Flächen zwischen den eben eingefügten Punkten erzeugt:
1 # Erste dreieckige Flaeche:
2 flaeche = NMesh.Face()
3 flaeche.v.append(viereck_mesh.verts[0])
4 flaeche.v.append(viereck_mesh.verts[1])
5 flaeche.v.append(viereck_mesh.verts[2])
6 viereck_mesh.faces.append(flaeche)
7
8 # Zweite dreieckige Flaeche:
9 flaeche = NMesh.Face()
10 flaeche.v.append(viereck_mesh.verts[2])
11 flaeche.v.append(viereck_mesh.verts[3])
12 flaeche.v.append(viereck_mesh.verts[0])
13 viereck_mesh.faces.append(flaeche)
(Man kann in diesem Fall auch eine viereckige Fläche erzeugen, hier zur Demonstration zwei Flächen.) Achtung: Der Drehsinn, in dem man die Punkte angibt, bestimmt die Richtung der Flächennormalen! Es ist erstrebenswert, dass die Normalen nach außen zeigen bzw. alle zur gleichen Seite. An den Normalen erkennt der Renderer, mit welcher Seite der Fläche er es zu tun hat, und falsche Normalen können falsche Schattierungen hervorrufen. Glücklicherweise gibt es in Blender auch die Funktion Recalculate Normals...
Ein Material und eine Textur hinzufügen
Ein Material weisen wir folgendermaßen zu:
1 # Erstelle neues Material:
2 material = Material.New("Rotes Material")
3 material.rgbCol = [0.8, 0.1, 0.1]
4
5 # Fuege Material zu dem Mesh hinzu:
6 viereck_mesh.materials.append(material)
Ein Material alleine ist recht langweilig, deswegen braucht es eine Textur:
1 # Erstelle neue Textur:
2 textur = Texture.New("Muster")
3 textur.setType("Voronoi")
4
5 # Fuege erstellte Textur zu Material hinzu:
6 material.setTexture(0, textur, Texture.TexCo.ORCO)
7
8 # Einige Einstellungen, wie die Textur gemappt weren soll:
9
10 # Das rot des Materials soll mit Weiss gemischt werden (je nach Helligkeit
11 # der Textur):
12 material.getTextures()[0].col = (1.0, 1.0, 1.0)
13
14 # Die Textur soll die Farbe und die Flaechennormalen der Textur beeinflussen:
15 material.getTextures()[0].mapto = Texture.MapTo.COL|Texture.MapTo.NOR
Das mag kompliziert aussehen, folgt aber genau der Vorgehensweise, eine Textur per Hand zuzuweisen:
Das gesamte Script sollte jetzt so aussehen: viereck.py
GUIs erzeugen
Um mit Scripten interagieren zu können, bietet Blender mit dem Modul Blender.Draw ein einfaches GUI-System an. Die wichtigste Funktion ist hierbei das Registrieren der GUI-Methoden:
1 from Blender import Draw
2 # ... hier GUI-Methoden definieren
3 Draw.Register(gui, event, bevent)
Der erste Parameter ist die Funktion, die für das Zeichnen der GUI zuständig ist, der zweite Parameter eine Funktion, welche allgemeine Events behandelt und der letzte Parameter eine Funktion, welche Button-Events behandelt.
Im Folgenden wollen wir eine einfache GUI mit einem Button erstellen. Die Blender-API kennt keine Events, stattdessen werden GUI-Objekten Integer-IDs zugewiesen, welche man in den Handler-Funktionen abfragen kann. Wir legen also für unseren Button eine Konstante fest:
1 QUIT_BUTTON = 1
Nun schreiben wir die Funktion, welche die GUI, also unseren Button, zeichnet:
1 def gui():
2 Draw.Button("Quit", QUIT_BUTTON, 40, 100, 150, 20)
Der erste Parameter zu Button ist die Aufschrift des Buttons, das zweite die besagte ID, die diesen Button kennzeichnet, der dritte und vierte Parameter legen die Position fest und die letzten beiden Parameter die Größe des Buttons.
Der allgemeine Event-Handler soll beim Drücken der Escape-Taste das Script beenden:
1 def event(evt, val):
2 if (evt == ESCKEY and not val):
3 Exit()
Die Variable val nimmt den Wert 0 an, wenn die Taste losgelassen wurde.
Beim Drücken unseres Buttons soll sich das Script ebenfalls beenden, deswegen sieht unser Button-Event-Handler wie folgt aus:
1 def bevent(evt):
2 if evt == QUIT_BUTTON:
3 Exit()
Damit sollte die GUI jetzt so aussehen:
Ein umfangreicheres GUI-Beispiel, ein 3D-Funktionsplotter, findet sich hier: fplot.py