Files
stylized-rock-generator/README.md
T
D4rkst3randClaude Opus 4.8 ef57050739 Neu: Stylized Asset Utils 1.0.0 (viertes Addon)
Fuer handgebaute Assets, die nicht durch einen Generator laufen (Pilze,
Baumstumpf, Erzfels, Props). Panel in fuenf einklappbaren Unter-Panels statt
einer langen Liste:

1 Vorbereiten  - Rotation/Scale anwenden, Ursprung unten-mittig, Normalen
2 Vertex-Farben - R=Cavity / G=Teil-oder-Moos-Maske / B=Hoehe / A=1
3 Benennung    - <Basis>_<NN>, Mesh-Daten ziehen mit
4 Pruefen      - Asset-Check auf alles, was in UE Aerger macht
5 Export       - FBX je Mesh mit colors_type='SRGB'

Zwei Bugs beim Bauen gefunden und gefixt:
- v.link_faces gibt es nur in bmesh, nicht auf Mesh.vertices -> lose Vertices
  ueber die tatsaechlich benutzten Indizes zaehlen.
- bpy.ops.paint.vertex_color_set braucht den Vertex-Paint-Modus und scheitert im
  Object-Mode mit "poll() failed". Zusammen mit vertex_color_dirt im selben try
  wurde dadurch der GANZE Bake stillschweigend uebersprungen (R/G/B blieben 1.0).
  Initialisierung laeuft jetzt direkt ueber Python.

Verifiziert am nachgebauten Pilz: Check meldet vorher Scale/Rotation/Ursprung,
nach "Vorbereiten" Scale 1/1/1, Rot 0/0/0, min_z 0.0000 und "ok". Teil-Maske
G=1 im Hut, 0 im Stiel. Nach FBX-Roundtrip G-Werte [0.0, 1.0] erhalten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-31 11:51:26 +02:00

362 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Stylized Asset Generators (Blender Addons)
> Dieses Repo liefert **zwei** Extensions ueber **eine** URL:
>
> | Addon | Panel | Zweck |
> |---|---|---|
> | **Stylized Rock Generator** | *Rock Gen* | Batch-Rocks + Textur-Bake + FBX/LOD-Export |
> | **Stylized Tree Generator** | *Tree Gen* | Baeume/Palmen/Bueschen/Kakteen (Geometry Nodes) mit Wachstums-Stufen |
> | **Stylized Grass Generator** | *Grass Gen* | Gras/Blumen/Farne mit Wind-UV fuer `SimpleGrassWind` |
> | **Stylized Asset Utils** | *Asset Utils* | **Handgebaute** Assets auf die Konvention bringen |
>
> Ein Blender-Extension-Repo kann mehrere Extensions ausliefern — `server-generate`
> listet jedes Zip in `dist/`. Ein „Check for Updates" aktualisiert also beide.
---
## EcoGame-Konventionen (beide Addons)
Abgestimmt auf `A:\eco\EcoGame` (UE 5.8). Kurzfassung:
**Benennung**
- Felsen: `Fels_<Form>_<Klasse>` — Form = Buchstabe (A, B, …), Klasse = `S/M/L/XL`.
Die Klasse setzt eine **Basis-Groesse** (S=0.45, M=1.0, L=1.9, XL=3.2) und ist
damit ein bewusst anderes Asset — gemessen: S 0.85 m, M 1.9 m, L 3.5 m, XL 6.0 m.
Davon strikt getrennt ist die **Zufalls-Streuung** (`scale_min/max`): die variiert
nur die FORM und wird von „Gesamtgroesse konstant halten" auf konstantes Volumen
normiert (1.11× statt 1.92×), damit sie sich nicht mit den ScaleMin/Max der Engine
multipliziert.
- Baeume: `<Art>_<Variante>_S<Stufe>`, z. B. `Birke_01_S1``Birke_01_S4`.
Zusatz-Ebenen haengen hinten an: `_Leaf`, `_Frucht`.
- Texturen: `<name>_albedo` und `<name>_normal` — mehr nicht.
**Textur-Bake**
- Nur **Albedo + Normal**. Roughness ist im Master-Material eine **Zahl**,
keine Textur.
- **AO/Cavity wird ins Albedo multipliziert** (Option „AO ins Albedo einrechnen",
Staerke regelbar). Dunkle Ritzen und helle Platten stecken im Farbbild — das
traegt den Stylized-Look. Separate Rough-/AO-Paesse sind Default **aus**.
- **Plattenstil (Genshin-Referenz):** Die Textur besteht aus **wenigen grossen,
fast leeren Platten** mit **schmalen dunklen Fugen** — das Detail steckt in der
Fuge, nicht in der Flaeche. Regler: `Plattengroesse` (kleiner = groessere
Platten), `Fugenbreite` (klein = harte Fuge, flache Platte), `Platten flach`
(1 = Flaeche nahezu einfarbig). Ein dichtes Zellmuster ueber die ganze
Oberflaeche erschlaegt die Form und passt NICHT zu diesem Look.
- **Vertex-Farb-Layout v2 (kanal-getrennt), Attribut `Cavity`:**
| Kanal | Inhalt |
|---|---|
| **R** | Cavity pur — 1 = offene Flaeche, 0 = tiefe Fuge (**ohne** Hoehen-Verlauf) |
| **G** | Moos-/Schmutzmaske — 1 = hier waechst was (Oberseite + Fugennaehe + Noise) |
| **B** | Hoehen-Verlauf — 0 = Unterseite, 1 = oben |
| **A** | 1 (Reserve) |
Getrennt statt eingebacken: der erdige **Boden-Saum** am Stein-Fuss und die
**Moosfarbe** werden pro Material-Instanz geregelt, nicht im Mesh festgelegt.
Regler: `Cavity-Staerke`, `Weichzeichnen`, `Moos-Menge`, `Moos-Aufbruch`,
`Moos-Seed`.
**G alternativ als Teil-Maske:** Haken `G = Teil-Maske (Shells)` markiert
getrennte Mesh-Teile statt Moos — der oberste/breiteste Teil bekommt 1, der
Rest 0. Assets, die aus mehreren Objekten mit **Strg+J** verbunden wurden
(Pilz = Hut + Stiel), lassen sich damit EXAKT trennen statt ueber Normalen
geschaetzt. Ein Material toent dann beide Teile unterschiedlich — **kein
zweiter Material-Slot noetig**. Einteilige Meshes bleiben unmarkiert (G=0).
**Der Button `Vertex-Cavity auf Auswahl` backt das Layout auf JEDES markierte
Mesh** — also auch auf handgebaute Assets, nicht nur auf generierte Steine.
Verifiziert: R ohne Hoehenabhaengigkeit (unten 0.62 / oben 0.59), B steigt
sauber (0.08 -> 0.92), G oben staerker (0.20 -> 0.57), A konstant 1,
Seed aendert die Verteilung, und alle Kanaele ueberleben den FBX-Roundtrip.
- **Texturfreie Alternative — Vertex-Cavity:** Statt zu baken laesst sich die
Cavity in die **Vertex-Farben** schreiben (Attribut `Cavity`, ueberlebt den
FBX-Roundtrip verlustfrei — gemessen 0.250..0.947 vor und nach dem Import).
Das Material braucht dann **keine Textur**:
`Base Color = Farbton x VertexColor`, dazu Kantenlicht (Fresnel) und
Schattentint. Vorteil gegenueber Triplanar: die dunklen Fugen sitzen auf den
ECHTEN Kanten des Meshes statt darueberzuschweben. Grenze: die Aufloesung
haengt an der Vertex-Dichte — fuer flaechige Platten reicht sie, fuer feine
Struktur nicht.
- 1024 px reicht fuer stylized Formen.
- Tileable (4D-Torus) passt zum triplanar mappenden Master-Material.
**Mesh**
- Echte Meter, Ursprung unten-mittig, FBX pro Asset bzw. LOD-Gruppe.
- **UV1 Lightmap ist Default aus** — EcoGame beleuchtet dynamisch.
- Meshes brauchen **keine eigenen Materialien**; in UE bekommt alles die
Material-Instanz vom Master. Ein Platzhalter im FBX ist okay.
- Scale-Randomisierung nur fuer die **Form** (nicht-uniform) nutzen, nicht fuer
die Gesamtgroesse — sonst multipliziert sie sich mit ScaleMin/Max der Engine.
---
## Stylized Asset Utils
Fuer alles, was **von Hand** gebaut wird (Pilze, Baumstumpf, Erzfels, Props) und
deshalb nicht durch einen Generator laeuft. Panel in fuenf einklappbaren Schritten:
1. **Vorbereiten** — Rotation/Scale anwenden, Ursprung unten-mittig, optional
Normalen neu berechnen. Damit steht das Asset in UE bei Scale 1 auf dem Boden.
2. **Vertex-Farben** — dasselbe Layout wie beim Rock Generator
(`R` = Cavity, `G` = Maske, `B` = Hoehe, `A` = 1).
`G` wahlweise als **Teil-Maske**: bei Assets, die mit **Strg+J** aus mehreren
Objekten verbunden wurden (Pilz = Hut + Stiel), bekommt der oberste Teil 1 und
der Rest 0 — exakt statt geschaetzt. **Ein** Material toent damit beide Teile,
ein zweiter Material-Slot entfaellt. Einteilige Meshes bleiben unmarkiert.
3. **Benennung** — Auswahl nach `<Basis>_<NN>` umbenennen, Mesh-Daten ziehen mit.
4. **Pruefen** — Asset-Check: nicht angewendete Transforms, Ursprung nicht unten,
Tri-Budget, fehlende UV/Vertex-Farben, lose Vertices, Custom Split Normals.
Details in der System-Konsole.
5. **Export** — FBX je Mesh mit `colors_type='SRGB'`, Triangulate und waehlbarem
Smoothing.
**Falle, die dabei auffiel:** `bpy.ops.paint.vertex_color_set` braucht den
Vertex-Paint-Modus und scheitert im Object-Mode mit „poll() failed". Steht es mit
`vertex_color_dirt` im selben `try`, wird der ganze Bake stillschweigend
uebersprungen. Die Initialisierung laeuft deshalb direkt ueber Python.
---
## Stylized Grass Generator
Gras-, Blumen- und Farn-Bueschel. Der Kern ist die **Wind-UV**:
- **UV0.V = 0 an der Wurzel, 1 an der Spitze** — genau die Maske, die UEs
`SimpleGrassWind` als *WindWeight* braucht. Ohne sie rutscht der Halm beim
Wehen vom Boden weg oder bewegt sich gar nicht.
Am Zielmaterial `M_Grass` geprueft: es liest `TextureCoordinate`, aber **keine**
`VertexColor` — deshalb liefert der Generator die Maske PRIMAER ueber die UV.
Die Assets funktionieren damit **ohne Materialaenderung**.
- **Vertex-Farben zusaetzlich** (nicht als einzige Quelle):
`R` = Kopie der Windmaske · `G` = Variation je HALM · `B` = AO (unten dunkel).
`G` ist die Ebene **unter** dem Biom-Tint, den die Engine ueber
`PerInstanceCustomData 0/1` pro Instanz setzt — im Material **multiplizieren**,
nicht ersetzen.
- Presets: `gras`, `gras_hoch`, `steppengras`, `farn`, `blume`.
- Tri-Budget-Warnung (Default 400 laut `ASSETS.md` fuer Gras/Blume).
Gemessen: ein Standard-Bueschel mit 14 Halmen = **112 Tris**.
- Ursprung unten-mittig (`min_z = 0.0000`), UV und Vertex-Farben ueberleben den
FBX-Roundtrip.
---
## Stylized Tree Generator
Parametrischer **Geaest**-Generator (Stamm + Aeste + Sub-Aeste) als Geometry-Nodes-
Gruppe. Blaetter/Krone macht man selbst — das Addon liefert die Struktur.
- **Presets:** `baum`, `palme`, `busch`, `tanne`, `eiche`, `birke`, `weide`,
`toter_baum`, `kaktus` — die Silhouette steuert die **Kronenform**
(`Crown Taper` / `Crown Bulge`, Idee aus modular_tree / Weber-Penn).
- **Tri-Budget:** alle Presets liegen unter dem Projektlimit (Baum ≤2500,
Busch ≤800). Stellschrauben: `Detail` (Segmente) und `Sides` / `Branch Sides` /
`Sub Sides` (Profilaufloesung je Ebene — Stamm rund, Zweige nur Dreiecke).
- **Wachstums-Stufen:** Haken setzen + Anzahl waehlen → Setzling bis ausgewachsen,
**gleicher Seed = dieselbe Baum-Identitaet** (fuer Wachstums-Systeme im Spiel).
- **Live bearbeiten:** Nach dem Erzeugen liegen alle Regler am Modifier `GN_Tree`
im Viewport ziehen, der Baum aktualisiert sich sofort.
- **Blattwerk:** Ein Blatt-/Billboard-Objekt als *Blatt-Card* waehlen (z. B. eine
Diamond-Plane mit Alpha-Textur) → der Button streut es auf die **Zweige** und legt
das Ergebnis als `<Name>_Leaf` mit identischem Ursprung ab. Gefiltert wird ueber
den Astradius (`Max Radius`), damit keine Blaetter am Stamm kleben. Ohne Card
bleibt `_Leaf` leer zum Selbermodellieren.
- **Tri-Budget:** Der Blattwerk-Button meldet `Stamm + Blatt = Summe` und **warnt**
bei Ueberschreitung. Default-Dichte 150 haelt auch das schwerste Preset (Eiche,
1428 Tris) mit 2460 von 2500 Tris im Budget.
- **Export:** „Modifier anwenden" friert das Ergebnis als normales Mesh ein.
**v1.1.0:** Aeste folgen jetzt der Elternkurve (Tangent/Normal aus *Curve to
Points*, Goldener Winkel = Phyllotaxis) statt einer aus Weltkoordinaten
gerechneten Richtung — Sub-Aeste standen vorher wie Nadeln quer zum Ast.
Neu: `Tip Blunt` (Baum laeuft spitz aus, Kaktus endet stumpf).
Der `kaktus` nutzt `Droop Curve` fuer den Saguaro-Ellbogen (Arm laeuft flach raus
und knickt dann steil hoch). Offen ist dort nur, dass die Rippen (`Ribs`) im
Shading kaum sichtbar sind.
---
# Stylized Rock Generator (Blender Addon)
Batch-Generator fuer stylized Rocks in Blender, ausgelegt auf den Export nach
**Unreal Engine 5** ueber FBX.
Pipeline pro Rock: Basis-Mesh (Cube / Ico-Sphere) → Subdivision Surface →
Displace mit prozeduraler Noise-Textur (Voronoi / Clouds / Distorted Noise) →
zweistufiges Decimate → Limited Dissolve → Normalen-Reparatur →
UV0 (Smart Project) + UV1 (Lightmap) → optional Bevel/Weighted Normal, Material,
LOD-Set, randomisierte Skalierung/Rotation.
Getestet mit **Blender 5.1.2** (Minimum laut `bl_info`: 4.2).
---
## Installation
1. `stylized_rock_generator.py` herunterladen.
2. Blender → *Edit → Preferences → Add-ons → Install…* → die `.py` waehlen.
3. Haken bei **Stylized Rock Generator** setzen.
4. Panel: *View3D → Sidebar (N) → Reiter "Rock Gen"*.
Update: einfach die neue `.py` erneut installieren (gleicher Modulname) oder das
Repo lokal ziehen und den Addon-Pfad in den Preferences auf den Repo-Ordner
zeigen lassen.
## Installation als Extension (via URL, mit Auto-Update)
Ab Blender 4.2 / 5.x als **Remote-Extension-Repository** einmal die URL
eintragen, danach gehen Updates per Klick.
1. Das Gitea-Repo muss **oeffentlich** sein (sonst kann Blender die Raw-URL nicht
ohne Login laden).
2. Blender → *Edit → Preferences → Get Extensions → oben rechts das Dropdown →
Repositories → „Add Remote Repository"*.
3. Als URL eintragen:
```
https://git.d4rkst3r.de/D4rkst3r/stylized-rock-generator/raw/branch/main/dist/index.json
```
4. „Check for Updates" aktivieren, bestaetigen. Die Extension erscheint in der
Liste → *Install*.
**Updaten (Maintainer-Seite):**
1. `version` in `blender_manifest.toml` (und `bl_info["version"]` in der `.py`) erhoehen.
2. `./build.ps1` (oder `blender --command extension build …` + `… server-generate …`).
3. `git add -A && git commit -m "vX.Y.Z" && git push`.
4. Nutzer: in Blender *Check for Updates* → *Update*.
Das gebaute Zip + `index.json` liegen in `dist/` und werden bewusst mitversioniert,
damit die Raw-URL sie ausliefert.
---
## Features
- **Basis-Formen:** Wuerfel, **Quader** oder Ico-Sphere, einstellbare Subsurf-Stufen.
Der Quader hat frei einstellbare `Quader-Proportionen` (X/Y/Z) plus
`Proportions-Streuung` — damit entstehen flache **Platten** und langgestreckte
**Riegel** statt nur runder Brocken. Gemessen bei Proportion (2.0, 1.5, 0.35):
3.43 / 2.56 / 0.79 m — Z also 23 % von X.
Die Proportionen werden auf **gleiches Volumen normiert** — „M" bedeutet damit
bei jeder Form dasselbe. Eine Platte ist dann flacher UND breiter als ein
Wuerfel derselben Klasse, aber nicht schwerer; ihre laengste Kante ist
entsprechend groesser (das ist Absicht, kein Fehler).
Die Proportionen werden auf die MESH-DATEN angewendet, nicht auf das Objekt:
der Displace nutzt globale Texturkoordinaten, eine Objekt-Skalierung wuerde
das Rauschen mitverzerren statt die Form zu aendern.
- **Noise/Displace:** Voronoi / Clouds / Distorted Noise, Scale + Staerke, Seed.
Seed-Variation ueber einen moderaten Welt-Offset (±25) vor dem Displace-Apply
Blenders prozedurale Texturen haben keinen echten Seed-Parameter.
- **Cleanup:** zweistufiges Decimate + Limited Dissolve, danach
`normals_make_consistent` (verhindert eingefallene/dunkle Flaechen).
- **UV fuer Unreal:** UV0 (Smart Project) fuer Material-Texturen, UV1 (Lightmap)
als separater, nicht ueberlappender Kanal fuer Static-Mesh-Lightmaps.
- **Hard-Surface (optional):** Bevel + Weighted Normal fuer einen "clean"
Kantenlook.
- **Material (Platzhalter):** weist pro Rock ein Material zu und rotiert durch
eine kleine Palette (Granite/Basalt/Sandstone/Mossy), damit nichts materiallos
exportiert wird.
- **LOD-Set:** erzeugt LOD0LODn als LOD-Gruppe fuer Unreal (siehe unten).
- **Presets:** eingebaute Presets (Kleiner Kiesel, Grosser Bruchfels, Lava-Rock)
plus eigene Presets als JSON (`rock_presets.json` neben dem Addon).
- **Batch:** synchron fuer kleine Mengen, ab `modal_threshold` (Default 25)
automatisch **modal mit Progress-Bar** die UI bleibt bedienbar, ESC bricht ab.
- **Robustheit:** Faellt ein einzelner Rock aus (z. B. 0 Faces nach zu
aggressivem Decimate), wird nur dieser uebersprungen und aufgeraeumt, der Rest
des Batches bleibt erhalten. Fehler landen in der System-Konsole.
---
## LOD-Export nach Unreal
Blenders FBX-Exporter kennt **keine** eigene LOD-Option. Unreal erkennt eine
LOD-Gruppe aber, wenn das Eltern-**Empty** die Custom Property
`fbx_type = "LodGroup"` traegt und die LOD-Meshes in Reihenfolge (LOD0…LODn)
darunter geparentet sind. Genau das erzeugt der Generator.
Beim FBX-Export darauf achten:
- **Custom Properties** aktivieren (sonst geht `fbx_type` verloren).
- Nur die LOD-Gruppe (Empty + Kinder) selektieren, `use_selection` an.
Beim Import in Unreal:
- Im FBX-Import-Dialog **Import LODs** aktivieren.
Referenz:
[Importing Static Mesh LODs Using FBX (UE Docs)](https://dev.epicgames.com/documentation/en-us/unreal-engine/importing-static-mesh-lods-using-fbx-in-unreal-engine).
---
## Tests
```bash
blender --background --python tests/test_rock_gen.py
```
Weitere Suiten (jeweils `blender --background --python <datei>`):
| Datei | prueft |
|---|---|
| `tests/test_tree_addon.py` | Tree-Addon: Presets, Wachstums-Stufen, UVs, Modifier-Apply |
| `tests/test_ecogame_rock.py` | Fels-Benennung, Bake liefert nur `_albedo`/`_normal`, AO im Albedo |
| `tests/test_ecogame_tree.py` | Baum-Benennung `<Art>_<Variante>_S<Stufe>`, Ursprung, Lightmap-Default |
| `tests/test_randomize.py` | Zufalls-Funktion beider Addons, `_Leaf`/`_Frucht` mit gleichem Ursprung |
| `tests/test_leaves.py` | Blattwerk: Streuung, Ursprung, Tri-Budget, leeres `_Leaf` ohne Card |
| `tests/test_rock_classes.py` | Groessen-Klassen S/M/L/XL unterscheiden sich, Streuung bleibt formbezogen |
Die Suiten erwarten die gebauten Zips in `dist/` bzw. lesen die `.py` direkt.
Erzeugt 3 Rocks, prueft je Rock: keine losen Vertices, manifold, Normalen nach
aussen (signed volume > 0), UV0 + UV1 vorhanden, und gibt eine Zusammenfassung
(Vertex-/Face-Count) aus. Exit-Code 0 = alles bestanden, 1 = Fehler.
---
## Changelog v2.3.0
- **Textur-Bake auf Zell-Look umgestellt:** Voronoi „Distance to Edge" liefert
hand-painted Zellen mit dunklen Outlines statt organischem fBm-Rauschen.
Neu regelbar: **Grundfarbe** und **Zellgroesse**. Weiterhin nahtlos tileable.
## Changelog v2.2.0
- **Textur-Bake-Button:** backt ein nahtlos **tileables** Stylized-Rock-Set
(BaseColor / Normal / Roughness / AO) als PNG. Nahtlos durch **4D-Torus-
Projektion** der UV (`cos/sin` von U und V) → tilet in beide Richtungen ohne
Naht, ideal fuer **Triplanar** in Unreal.
- Anleitung zur UE-Material-Verdrahtung: siehe
[docs/UE_Material_Triplanar.md](docs/UE_Material_Triplanar.md).
## Changelog v2.1.0
- **FBX-Export-Button (UE-ready):** exportiert jeden Rock / jede LOD-Gruppe als
eigene FBX mit `use_custom_props=True` (fuer `fbx_type=LodGroup`), Triangulate
und passendem Smoothing (`EDGE` bei Auto-Smooth, sonst `FACE`).
*UE-Import-Tipp:* Normal Import Method auf „Import Normals" stellen, „Import LODs" an.
- **Shading-Toggle:** Faceted / Smooth / Auto-Smooth-nach-Winkel.
- **Pro-Rock-Varianz:** Noise-Scale & Displace-Staerke zwischen Min/Max plus
optionale nicht-uniforme Skalierung → ein Batch wirkt variantenreich.
- **Boden abflachen (Bisect) + Origin unten-mittig** → Rocks stehen in UE plan auf.
## Changelog v2.0.0
Gehaertet & erweitert gegenueber v1.0.0:
- **Bugfix:** `smart_project(angle_limit=…)` ist in Blender 4.x/5.x in **Radiant**
(`[0, 1.5708]`) der alte Wert `66.0` war ungueltig. Jetzt `radians(66°)`.
- **Bugfix:** `dissolve_limited(angle_limit=…)` erwartet **Radiant**; der
Grad-Wert wurde ungewandelt durchgereicht → uebermaessiges Dissolve. Jetzt
`radians(dissolve_angle)`.
- **Bugfix:** Der Lightmap-Kanal wurde vor `lightmap_pack` nicht als aktiver
UV-Layer gesetzt → UV0 konnte ueberschrieben werden. Jetzt explizit gesetzt,
UV0 danach wieder als Render-Kanal.
- Fehlerbehandlung um jeden `bpy.ops.*`-Aufruf; einzelne Rock-Fehler brechen den
Batch nicht mehr ab.
- Nicht-blockierender modaler Batch-Modus mit Progress-Bar.
- Bevel + Weighted Normal als Toggle.
- LOD-Set als `fbx_type=LodGroup`-Gruppe.
- Preset-System (JSON) mit Panel-Dropdown.
- Platzhalter-Material-Zuweisung.