Recent Changes - Search:

Blender Technical Director?

pmwiki.org

edit SideBar

BTD /

Lab1

BTD/Modul 1: Übungen

Aufgabe 1: Scene Explorer

Erstellen Sie ein Python-Skript, das alle Objekte, Collections, Modifiers und Materialien einer Szene auflistet.

  • Geben Sie die Informationen in einer strukturierten Tabelle oder Liste aus.
  • Kennzeichnen Sie Objekte nach Typ (Mesh, Light, Camera, Curve).
  • Bonus: Funktion schreiben, die ungenutzte Datenblöcke erkennt und meldet.

Aufgabe 2: Dependency Graph Visualizer

  • Schreiben Sie ein Script, das die Abhängigkeiten zwischen Objekten analysiert.
  • Ausgabe: Welche Objekte sind voneinander abhängig?
  • Optional: Markieren Sie zyklische Abhängigkeiten oder Konflikte.

Aufgabe 3: Modifier Report

  • Prüfen Sie alle Mesh-Objekte auf aktive Modifier.
  • Listen Sie Typ, Status (enabled/disabled) und Reihenfolge auf.
  • Bonus: Automatische Deaktivierung von Modifiern implementieren.

BTD / Modul 1: Erweiterte Übungen

Diese Ü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.

  • Listen Sie auf:
    • Objekte
    • Collections (inkl. Hierarchie)
    • Materialien
    • Modifier
    • Verknüpfte Datenblöcke (Meshes, Lights, Cameras)
  • Kennzeichnen Sie Objekte nach Typ (Mesh, Light, Camera, Curve, Empty).
  • Geben Sie an, ob Datenblöcke mehrfach verwendet werden (Shared Data).

Bonus (TD-Realismus):

  • Erkennen Sie ungenutzte Datenblöcke (`users == 0`).
  • Geben Sie eine Warnung für Namenskonflikte aus (z. B. `Cube`, `Cube.001`).

'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 Detective

In realen Produktionen werden Szenen über Collections strukturiert.

  • Schreiben Sie ein Skript, das:
    • die Collection-Hierarchie rekursiv ausgibt
    • anzeigt, welche Objekte in mehreren Collections liegen
    • Hidden / Disabled Collections kennzeichnet

Bonus:

  • Erkennen Sie "verwaiste" Objekte, die nur in der Master Collection liegen.

'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.

  • Analysieren Sie:
    • Parenting
    • Constraints
    • Modifier-Abhängigkeiten (z. B. Boolean, Armature)
  • Geben Sie für jedes Objekt seine direkten Abhängigkeiten aus.

Optional (Advanced):

  • Erkennen Sie zyklische Abhängigkeiten
  • Visualisieren Sie das Ergebnis als ASCII-Graph oder DOT-Output

'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 & Optimizer

Analysieren Sie alle Mesh-Objekte in der Szene.

  • Listen Sie für jedes Objekt:
    • Modifier-Typ
    • Reihenfolge
    • Viewport- und Render-Status
  • Kennzeichnen Sie teure Modifier (Subdivision, Boolean, Solidify).

Bonus (Production-TD):

  • Schreiben Sie eine Funktion, die:
    • alle Subdivision Modifier im Viewport deaktiviert
    • aber für den Render aktiv lässt

'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 Check

Kombinieren Sie alle vorherigen Aufgaben zu einem *automatischen Szenen-Audit*.

Das Skript soll u. a. melden:

  • Ungenutzte Datenblöcke
  • Objekte ohne Collection-Struktur
  • Übermäßig viele Modifier
  • Zyklische Abhängigkeiten

Ausgabe:

  • Konsolen-Report
  • Optional: Text-Block im Blender Text Editor

Lernziel: Denken wie ein Technical Director: Analyse, Automatisierung, Prävention.

---

Hinweis für Studierende

Diese Übungen sind absichtlich offen gestaltet. Es gibt **nicht die eine richtige Lösung** – entscheidend ist:

  • saubere API-Nutzung
  • nachvollziehbare Struktur
  • Erweiterbarkeit

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 Materialien

Das 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

  • Volle Kontrolle über **Sampling & Auflösung**
  • Grundlage für:
    • Baking
    • Texture Tools
    • Export-Pipelines
  • Verständnis für:
    • Noise-Implementierungen
    • Filter & Mipmaps

---

Challenge

  • Implementiere **Perlin Noise vollständig selbst**
  • Baue Multi-Octave Fractals
  • Erzeuge Normal-Maps aus Höhenfeldern

Lernziel: Algorithmische Bildsynthese, Datenorientiertes Denken, Pipeline-Kompetenz.

Edit - History - Print - Recent Changes - Search
Page last modified on January 11, 2026, at 10:03 PM UTC