Mithilfe von Blender erstellen Sie eigene 3D-Modelle bis hin zu Animationen. Wir zeigen Ihnen, wie Sie sich teilautomatisiert ein virtuelles Uhrenmodell mit Blender und Python zusammenbauen.
Das kostenlose Programmpaket Blender zur Modellierung, Texturierung, Animation, Video- und Bildbearbeitung findet sich in den Paketquellen der meisten Linux-Distributionen und als distributionsübergreifendes Snap-Paket. Auf der Kommandozeile installiert der Befehl snap install blender die Grafiksuite. Genügt Ihnen das als Installationsmöglichkeit nicht, laden Sie die Anwendung direkt von der Webseite der Blender Foundation [1] herunter. Dort greifen Sie außerdem auf die umfangreiche Dokumentation, Tutorials und Beispiele zu und beziehen die Versionen für Windows, MacOS und andere. Da die Blender Foundation darüber hinaus den Quellcode zur Verfügung stellt, lässt sich das Programm selbst an exotische Betriebssysteme anpassen. In diesem Fall müssen Sie jedoch selbst kompilieren.
Unter Linux öffnen Sie Blender entweder aus einem Terminal heraus oder über eine Verknüpfung der Art Im Terminal öffnen im Fenstermanager Ihrer Wahl. Gelingt beides nicht, starten Sie zunächst Blender und versuchen dann, in der Python Interactive Console mittels bpy.app.binary_path den Pfad der Blender-Installation herauszufinden. Den geben Sie anschließend als Startparameter hinter dem Aufruf im Terminal an. Das sorgt dafür, dass auch Fehlermeldungen und Ausgaben etwa des Python-Kommandos print("Hallo Welt") ihr Ziel erreichen, nämlich das Terminalfenster. Wichtig ist das vor allem dann, wenn Sie nicht nur die Blender Python Console in Blenders Scripting Workspace und einzelne Befehle verwenden wollen, sondern bereits gespeicherte Python-Programme aufrufen möchten.
Arbeitsoberfläche
Die Bedienoberfläche von Blender unterteilt sich in Workspaces. Hinter jedem davon steckt eine andere Sammlung von Editoren und Fenstern, die an speziellen Positionen auf dem Bildschirm erscheinen. Verfügbare Workspaces listet das Programm rechts unterhalb der Menüleiste auf, darunter Layout, Modeling, Sculpting, UV Editing und Animation. Nahezu sämtliche Workspaces enthalten das 3D-Viewport-Window und weitere Fenster.
Abbildung 1 zeigt Blender nach dem Start mit der Standard-Grundszene. Grundsätzlich können Sie sich Ihre 3D-Szenen nach Herzenslust direkt in der Oberfläche zusammenbauen. Für den Einstieg in die Bedienung von Blender gibt es zahlreiche Tutorials im Internet; eine Beschreibung würde den Rahmen dieses Artikels aufgrund des Funktionsumfangs sprengen. Das Ziel liegt vielmehr darin, Sie in die Lage zu versetzen, sich Hilfsmittel in Form von Python-Skripten zu schreiben, mit denen Sie komplexe Szenen skriptgesteuert nacheinander aufbauen.

Abbildung 1: Blender mit der Standard-Grundszene mit 3D-View, perspektivischer Ansicht auf einen Würfel, einer Kamera und einer Lichtquelle.
Zifferblatt
Als Beispiel soll uns hier ein dreidimensionales Zifferblatt einer Uhr mit erhabenen Ziffern und Zeigern dienen. Interessant ist in dem Zusammenhang die Positionierung der Ziffern auf dem Zifferblatt, die ausschließlich unter Verwendung der trigonometrischen Funktionen in der Mathematik korrekt gelingt.
Zunächst setzen Sie das Zifferblatt noch teilweise manuell zusammen, lernen dabei aber gleichzeitig etwas Blender-Python kennen. Schalten Sie dazu auf den Workspace Scripting um. Daraufhin gelangen Sie in eine Programmieroberfläche (Abbildung 2). Links sehen Sie das bereits bekannte, etwas verkleinerte 3D-Viewport-Fenster. Darunter befinden sich die Blender Python Console und die Infozeile. Ein Mausklick auf Add | Mesh | Plane lässt eine quadratische Grundfläche für das Zifferblatt entstehen. Parallel protokolliert Blender links unten im Infofenster Ihre manuelle Aktion. Das liest sich wie in der ersten Zeile von Listing 1.
Listing 1
Blender-Aktion
bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
bpy.ops.mesh.primitive_plane_add(size=5)
{'FINISHED'}
Eines vorweg: Blender leitet Tastatureingaben direkt in das Fenster weiter, über dem sich der Mauszeiger befindet. Dementsprechend brauchen Sie das Fenster zuvor nicht anzuklicken. Sie sollten aber gerade im Scripting-Workspace bei Tastatureingaben genau darauf achten, dass der Mauszeiger an der richtigen Stelle steht. Bewegen Sie ihn im ersten Schritt über das 3D-Viewport-Fenster, drücken Sie [X] und bestätigen Sie die Löschen-Sicherheitsabfrage. Die quadratische Grundfläche sollte wieder verschwinden und eine weitere Zeile im Infofenster erscheint als Protokollierung.
Anschließend bauen Sie die quadratische Grundfläche noch einmal auf, diesmal allerdings in einer anderen Größe und mittels Befehlseingabe in der Blender Python Console (Listing 1, Zeile 2). Im 3D-Viewport-Fenster zeigt das Programm nun die quadratische Grundfläche in einer größeren Variante. In der Blender Python Console erscheint eine positive Rückmeldung (Zeile 3). In der darunter befindlichen Infozeile steht der Protokolleintrag in vollständiger Form inklusive aller nicht mit angegebener Standardwerte.

Abbildung 2: Bei aktiviertem Scripting-Workspace zeigt die Anwendung neben dem 3D-Viewport-Fenster die Blender Python Console und eine Infozeile an.
Wenn Sie sich als kleine Übung vor dem eigentlichen Bau des Zifferblatts mit der Arbeitsweise von Variablen und Schleifen vertraut machen möchten, erstellen Sie zunächst eine kleine Pyramide. Dazu geben Sie in der Blender Python Console den Code aus Listing 2 ein. Beachten Sie dabei, dass Schleifen in Python grundsätzlich durch Einrückungen des Schleifenblocks gebildet werden. In der Blender Python Console beenden Sie die Einrückung mithilfe einer Leerzeile am Ende der Schleife.
Listing 2
Pyramidenbau
i=1 while i < 9: bpy.ops.mesh.primitive_cube_add(size=1, enter_editmode=False, align='WORLD', location=(0, 0, i-0.5), scale=(9-i, 9-i, 1)) i+=1
Schlüsselkonzepte
Sie können auf die Daten innerhalb von Blender mit der Python-API auf dieselbe Art und Weise zugreifen wie über die Benutzeroberfläche. Grundsätzlich gilt: Was Sie über Schalter, Tasten und Menüeinträge erreichen, lässt sich auch mit Python ansteuern. Sämtliche Daten der aktuell geladenen Blender-Datei erreichen Sie über das Modul bpy.data.
Die Anwendung organisiert die Daten in Collections, auf die Sie entweder mittels Index oder Zeichenkette zugreifen. Im Outliner gibt es nach dem Start des Programms mit der Standardszene genau drei Objekte: bpy.data.objects['Camera'], bpy.data.objects['Cube'] und bpy.data.objects['Light']. Objekte lassen sich zudem über Indexnummern abrufen, der Würfel beispielsweise via bpy.data.objects[1].
Wie von der dialogorientierten Oberfläche gewohnt, wählen Sie hier das Objekt häufig nicht durch Eingeben des Namens aus, sondern mithilfe der Maus. Es lassen sich sogar beliebig viele Objekte gleichzeitig herausgreifen, um sie zum Beispiel gemeinsam zu verschieben. Allerdings fungiert dabei nur eines davon als aktives Objekt, auf das sich alle Aktionen beziehen. Außerdem stammen sämtliche angezeigten Werte von diesem Objekt. Operationen, die auf mehrere Objekte wirken sollen, verwenden es als Referenz, beispielsweise beim Zuweisen eines anderen Materials.
Auf das aktive Objekt greifen Sie innerhalb von Python über das Kommando bpy.context.object zu, auf alle ausgewählten Objekte mit bpy.context.selected_objects. Der Zugriff auf diesen sogenannten Context funktioniert jedoch lediglich lesend. Um die Werte zu ändern, müssen Sie API-Funktionen aufrufen oder bpy.data nutzen.
Listing 3 zeigt den Teil des Python-Skripts, der das Positionieren der Ziffern auf dem Zifferblatt übernimmt (Abbildung 3). Da die dreidimensionalen Ziffern unterschiedlich breit und hoch ausfallen, müssen Sie hier auf die korrekte Einstellung des Ursprungspunkts der Zahlen auf dem Zifferblatt achten. Das gewährleistet eine korrekte Zentrierung der ein- und zweistelligen Zahlen. Abbildung 4 veranschaulicht den Zusammenhang der trigonometrischen Funktionen aus Listing 4. Listing 5 zeigt das gesamte Skript, das Sie auch im Download-Bereich zu diesem Artikel finden [2].
Listing 3
Vorbereitungen und Aufräumarbeiten
import bpy import math import datetime bpy.ops.object.select_pattern(pattern='Text*') bpy.ops.object.select_pattern(pattern='*zeiger') bpy.ops.object.select_pattern(pattern='Plane') bpy.ops.object.delete() stunde = datetime.datetime.now().hour minute = datetime.datetime.now().minute stundenwinkel = 360 / 12 * (stunde + minute/60) minutenwinkel = 360 / 60 * minute fromCenter = 3 angleInc = 30 * math.pi/180 bpy.ops.mesh.primitive_plane_add(size=9, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
Listing 4
Positionierung der Ziffern
i = 1
while i <= 12:
x=fromCenter * math.sin(angleInc * i)
y=fromCenter * math.cos(angleInc * i)
z=0.2
bpy.ops.object.text_add(location=(x,y,z))
ob=bpy.context.object
ob.data.body = str(i)
ob.modifiers.new("SOLIDIFIED TEXT","SOLIDIFY").thickness=0.2
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')
i+=1
Listing 5
Das fertige Python-Skript
import bpy
import math
import datetime
bpy.ops.object.select_pattern(pattern='Text*')
bpy.ops.object.select_pattern(pattern='*zeiger')
bpy.ops.object.select_pattern(pattern='Plane')
bpy.ops.object.delete()
stunde = datetime.datetime.now().hour
minute = datetime.datetime.now().minute
stundenwinkel = 360 / 12 * (stunde + minute/60)
minutenwinkel = 360 / 60 * minute
fromCenter = 3
angleInc = 30 * math.pi/180
bpy.ops.mesh.primitive_plane_add(size=9, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))
i = 1
while i <= 12:
x=fromCenter * math.sin(angleInc * i)
y=fromCenter * math.cos(angleInc * i)
z=0.2
bpy.ops.object.text_add(location=(x,y,z))
ob=bpy.context.object
ob.data.body = str(i)
ob.modifiers.new("SOLIDIFIED TEXT","SOLIDIFY").thickness=0.2
bpy.ops.object.origin_set(type='GEOMETRY_ORIGIN', center='MEDIAN')
i+=1
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0.05), rotation=(0, 0, 0), scale=(1, 1, 1))
bpy.context.selected_objects[0].name="Stundenzeiger"
bpy.context.selected_objects[0].dimensions=( 0.2, 2, 0.1)
bpy.ops.transform.translate(value=(0, 1, 0))
bpy.context.scene.tool_settings.use_transform_data_origin = True
bpy.ops.transform.translate(value=(0, -1, 0))
bpy.context.scene.tool_settings.use_transform_data_origin = False
bpy.ops.transform.rotate(value= stundenwinkel * math.pi/180)
bpy.context.object.lock_location[0] = True
bpy.context.object.lock_location[1] = True
bpy.context.object.lock_location[2] = True
bpy.context.object.lock_rotation[0] = True
bpy.context.object.lock_rotation[1] = True
bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0.1), rotation=(0, 0, 0), scale=(1, 1, 1))
bpy.context.selected_objects[0].name="Minutenzeiger"
bpy.context.selected_objects[0].dimensions=( 0.2, 2.6, 0.1)
bpy.ops.transform.translate(value=(0, 1.3, 0))
bpy.context.scene.tool_settings.use_transform_data_origin = True
bpy.ops.transform.translate(value=(0, -1.3, 0))
bpy.context.scene.tool_settings.use_transform_data_origin = False
bpy.ops.transform.rotate(value= minutenwinkel * math.pi/180)
bpy.context.object.lock_location[0] = True
bpy.context.object.lock_location[1] = True
bpy.context.object.lock_location[2] = True
bpy.context.object.lock_rotation[0] = True
bpy.context.object.lock_rotation[1] = True
Fazit
Mit Blender erhalten Sie eine kostenlose professionelle 3D- und Animationssoftware, die unter anderem sogar in Kurzfilmen auf DVD, in Youtube-Clips und Animationsprojekten sowie bei Spieleentwicklern zum Einsatz kommt. Entsprechend der vielen Einsatzmöglichkeiten fällt zu Beginn der Arbeit mit Blender die Lernkurve relativ steil aus. Im Gegenzug setzt das Programm anschließend beim Gestalten den eigenen Fähigkeiten kaum noch Grenzen. Wenn Sie genug Zeit und Mühe investieren, können sich die Ergebnisse durchaus sehen lassen, wie das Aufmacherbild dieses Artikels demonstriert. (csi)
Der Autor
Ralf Kirschner arbeitete als Visual-Basic-Programmierer in einem Software- und Systemhaus. Der ausgebildete Systemadministrator erteilt freiberuflich Computerschulungen.
Infos
-
Blender Foundation: https://www.blender.org/
-
Uhrenbau-Skript herunterladen: http://www.cssenior.de/BlenderUhrenbau/uhrenbau.py.txt







