|
BTD /
Lab1BTD/Modul 1: ÜbungenAufgabe 1: Scene ExplorerErstellen Sie ein Python-Skript, das alle Objekte, Collections, Modifiers und Materialien einer Szene auflistet.
Aufgabe 2: Dependency Graph Visualizer
Aufgabe 3: Modifier Report
BTD / Modul 1: Erweiterte ÜbungenDiese Übungen sind so konzipiert, dass Studierende Blender nicht nur *bedienen*, sondern als *Software-System* verstehen. Jede Aufgabe kombiniert technische Analyse, API-Nutzung und praxisnahe TD-Szenarien. --- Aufgabe 1: Scene Explorer++ ("Was ist wirklich in meiner Szene?")Erstellen Sie ein Python-Skript, das die komplette Struktur einer Blender-Szene analysiert und protokolliert.
Bonus (TD-Realismus):
'Beispiel-Code: Scene Explorer' ```python import bpy print("=== Scene Explorer ===") for obj in bpy.context.scene.objects: data = obj.data
data_name = data.name if data else "<None>"
users = data.users if data else 0
print(f"Object: {obj.name}")
print(f" Type: {obj.type}")
print(f" Data: {data_name} (users: {users})")
if obj.modifiers:
print(" Modifiers:")
for mod in obj.modifiers:
print(f" - {mod.type} | enabled: {mod.show_viewport}")
else:
print(" Modifiers: none")
print("\n=== Unused Data Blocks ===") for mesh in bpy.data.meshes: if mesh.users == 0:
print(f"Unused mesh: {mesh.name}")
``` Lernziel: Verständnis des Data-Block-Systems und der Trennung von Objekt und Daten. --- Aufgabe 2: Collection & Layer DetectiveIn realen Produktionen werden Szenen über Collections strukturiert.
Bonus:
'Beispiel-Code: Collection Tree' ```python import bpy def print_collection(col, indent=0): prefix = " " * indent
print(f"{prefix}- Collection: {col.name}")
for obj in col.objects:
print(f"{prefix} Object: {obj.name}")
for child in col.children:
print_collection(child, indent + 1)
print_collection(bpy.context.scene.collection) ``` Lernziel: Szenenorganisation, Rekursion, Produktions-Workflows. --- Aufgabe 3: Dependency Graph Visualizer ("Wer beeinflusst wen?")Technische Direktoren müssen Abhängigkeiten verstehen, bevor sie optimieren.
Optional (Advanced):
'Beispiel-Code: Simple Dependency Scan' ```python import bpy for obj in bpy.context.scene.objects: print(f"Object: {obj.name}")
if obj.parent:
print(f" Parent: {obj.parent.name}")
for con in obj.constraints:
if hasattr(con, "target") and con.target:
print(f" Constraint -> {con.target.name}")
``` Lernziel: Grundlagen des Dependency Graphs und typische Fehlerquellen. --- Aufgabe 4: Modifier Report & OptimizerAnalysieren Sie alle Mesh-Objekte in der Szene.
Bonus (Production-TD):
'Beispiel-Code: Modifier Optimizer' ```python import bpy for obj in bpy.context.scene.objects: if obj.type != 'MESH':
continue
for mod in obj.modifiers:
print(f"{obj.name} | {mod.type} | viewport: {mod.show_viewport}")
if mod.type == 'SUBSURF':
mod.show_viewport = False
``` Lernziel: Performance-Denken und technische Szenenoptimierung. --- Aufgabe 5 (Challenge): Scene Health CheckKombinieren Sie alle vorherigen Aufgaben zu einem *automatischen Szenen-Audit*. Das Skript soll u. a. melden:
Ausgabe:
Lernziel: Denken wie ein Technical Director: Analyse, Automatisierung, Prävention. --- Hinweis für StudierendeDiese Übungen sind absichtlich offen gestaltet. Es gibt **nicht die eine richtige Lösung** – entscheidend ist:
In späteren Modulen werden diese Werkzeuge weiterverwendet und ausgebaut. Prozedurale Texturen durch Pixel-Manipulation (Python)In diesen Beispielen werden **Texturen vollständig algorithmisch erzeugt**, indem **jedes einzelne Pixel** einer neuen `Image`-Datenstruktur in Blender berechnet und gesetzt wird. Kein Shader-Noise, keine Nodes, keine Materialien. ➡️ **Reine Datenebene (Image Data Block)** – exakt das, was TDs für Baking, Tools und Pipelines benötigen. --- Grundgerüst: Image anlegen & Pixel schreiben```python import bpy import math width, height = 512, 512 img = bpy.data.images.new( name="Procedural_Image",
width=width,
height=height,
alpha=True,
float_buffer=False
) pixels = [0.0] * (width * height * 4) # RGBA ``` Am Ende jedes Beispiels: ```python img.pixels = pixels img.update() ``` 0. Vollständiges Beispiel:```python import bpy import math width, height = 512, 512 img = bpy.data.images.new( name="Procedural_Image",
width=width,
height=height,
alpha=True,
float_buffer=False
) pixels = [] for w in range(width): for h in range(height):
pixels.append(math.sin(0.1*w)+math.cos(0.1*h))
pixels.append(math.cos(h))
pixels.append(math.sin(w))
pixels.append(1.0)
img.pixels = pixels img.update() ``` --- 1. Linearer Grauverlauf (Basisfall)```python for y in range(height): for x in range(width):
i = (y * width + x) * 4
v = x / width
pixels[i:i+4] = (v, v, v, 1.0)
``` Formel: ``` f(x) = x / width ``` --- 2. Radialer Verlauf (Kreisdistanz)```python cx, cy = width / 2, height / 2 max_d = math.sqrt(cx*cx + cy*cy) for y in range(height): for x in range(width):
dx = x - cx
dy = y - cy
d = math.sqrt(dx*dx + dy*dy) / max_d
i = (y * width + x) * 4
pixels[i:i+4] = (d, d, d, 1.0)
``` --- 3. Schachbrett (Modulo-Logik)```python size = 32 for y in range(height): for x in range(width):
v = ((x // size) + (y // size)) % 2
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` --- 4. Sinus-Streifen```python frequency = 20.0 for y in range(height): for x in range(width):
v = (math.sin(x / width * frequency * math.pi * 2) + 1) / 2
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` --- 5. Pseudo-Random Noise (Hash)```python import random random.seed(0) for y in range(height): for x in range(width):
v = random.random()
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` Deterministisch (Alternative): ```python def hash(x, y): return math.fmod(math.sin(x*12.9898 + y*78.233) * 43758.5453, 1.0) for y in range(height): for x in range(width):
v = abs(hash(x, y))
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` --- 6. Value Noise (Interpolation selbst gebaut)```python def lerp(a, b, t): return a + t * (b - a) cell = 32 for y in range(height): for x in range(width):
x0 = (x // cell) * cell
y0 = (y // cell) * cell
x1 = x0 + cell
y1 = y0 + cell
h00 = hash(x0, y0)
h10 = hash(x1, y0)
h01 = hash(x0, y1)
h11 = hash(x1, y1)
tx = (x - x0) / cell
ty = (y - y0) / cell
a = lerp(h00, h10, tx)
b = lerp(h01, h11, tx)
v = lerp(a, b, ty)
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` --- 7. Ringe / Holzjahresringe```python cx, cy = width/2, height/2 for y in range(height): for x in range(width):
dx = x - cx
dy = y - cy
r = math.sqrt(dx*dx + dy*dy)
v = (math.sin(r * 0.15) + 1) / 2
i = (y * width + x) * 4
pixels[i:i+4] = (v, v, v, 1.0)
``` --- Einbindung in MaterialienDas erzeugte Image kann direkt verwendet werden: ```python mat = bpy.data.materials.new("Pixel_Material") mat.use_nodes = True nodes = mat.node_tree.nodes tex = nodes.new("ShaderNodeTexImage") tex.image = img ``` --- Warum das für Technical Directors zentral ist
--- Challenge
Lernziel: Algorithmische Bildsynthese, Datenorientiertes Denken, Pipeline-Kompetenz. |