Tree Generator v1.10.0: Kronenform + 5 neue Baum-Varianten
Crown Taper / Crown Bulge steuern die botanische Huellkurve (kegelfoermig bis rund) - damit sind Tanne, Eiche, Birke, Weide und toter Baum als Presets moeglich. Alle neun Presets liegen im Tri-Budget des Projekts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,12 @@
|
|||||||
Parametrischer **Geaest**-Generator (Stamm + Aeste + Sub-Aeste) als Geometry-Nodes-
|
Parametrischer **Geaest**-Generator (Stamm + Aeste + Sub-Aeste) als Geometry-Nodes-
|
||||||
Gruppe. Blaetter/Krone macht man selbst — das Addon liefert die Struktur.
|
Gruppe. Blaetter/Krone macht man selbst — das Addon liefert die Struktur.
|
||||||
|
|
||||||
- **Presets:** `baum`, `palme`, `busch`, `kaktus`
|
- **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,
|
- **Wachstums-Stufen:** Haken setzen + Anzahl waehlen → Setzling bis ausgewachsen,
|
||||||
**gleicher Seed = dieselbe Baum-Identitaet** (fuer Wachstums-Systeme im Spiel).
|
**gleicher Seed = dieselbe Baum-Identitaet** (fuer Wachstums-Systeme im Spiel).
|
||||||
- **Live bearbeiten:** Nach dem Erzeugen liegen alle Regler am Modifier `GN_Tree` —
|
- **Live bearbeiten:** Nach dem Erzeugen liegen alle Regler am Modifier `GN_Tree` —
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
schema_version = "1.0.0"
|
schema_version = "1.0.0"
|
||||||
|
|
||||||
id = "stylized_tree_generator"
|
id = "stylized_tree_generator"
|
||||||
version = "1.9.0"
|
version = "1.10.0"
|
||||||
name = "Stylized Tree Generator"
|
name = "Stylized Tree Generator"
|
||||||
tagline = "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen"
|
tagline = "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen"
|
||||||
maintainer = "D4rkst3r"
|
maintainer = "D4rkst3r"
|
||||||
|
|||||||
Vendored
+4
-4
@@ -32,7 +32,7 @@
|
|||||||
"id": "stylized_tree_generator",
|
"id": "stylized_tree_generator",
|
||||||
"name": "Stylized Tree Generator",
|
"name": "Stylized Tree Generator",
|
||||||
"tagline": "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen",
|
"tagline": "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen",
|
||||||
"version": "1.9.0",
|
"version": "1.10.0",
|
||||||
"type": "add-on",
|
"type": "add-on",
|
||||||
"maintainer": "D4rkst3r",
|
"maintainer": "D4rkst3r",
|
||||||
"license": [
|
"license": [
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
"Mesh",
|
"Mesh",
|
||||||
"Modeling"
|
"Modeling"
|
||||||
],
|
],
|
||||||
"archive_url": "./stylized_tree_generator-1.9.0.zip",
|
"archive_url": "./stylized_tree_generator-1.10.0.zip",
|
||||||
"archive_size": 14478,
|
"archive_size": 15650,
|
||||||
"archive_hash": "sha256:07c964096cd907dab9e22e1bc936621ed25476e188ebaa6176a18e98c5f76a4c"
|
"archive_hash": "sha256:995b37759449eab7f767bc87dcd7917bdac4382c3a2a8d37e1e0c9dc9d11eb30"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
bl_info = {
|
bl_info = {
|
||||||
"name": "Stylized Tree Generator",
|
"name": "Stylized Tree Generator",
|
||||||
"author": "D4rkst3r",
|
"author": "D4rkst3r",
|
||||||
"version": (1, 9, 0),
|
"version": (1, 10, 0),
|
||||||
"blender": (4, 2, 0),
|
"blender": (4, 2, 0),
|
||||||
"location": "View3D > Sidebar > Tree Gen",
|
"location": "View3D > Sidebar > Tree Gen",
|
||||||
"description": "Parametrischer Baum-/Palmen-/Busch-Generator (Geometry Nodes) mit Wachstums-Stufen",
|
"description": "Parametrischer Baum-/Palmen-/Busch-Generator (Geometry Nodes) mit Wachstums-Stufen",
|
||||||
@@ -49,6 +49,8 @@ DEFAULTS = {
|
|||||||
"Sub Sides": 3, # Zweige nur Dreiecke - sieht man nicht
|
"Sub Sides": 3, # Zweige nur Dreiecke - sieht man nicht
|
||||||
"UV Scale": 1.0, # Rinden-Dichte; UVs sind world-space (m)
|
"UV Scale": 1.0, # Rinden-Dichte; UVs sind world-space (m)
|
||||||
"Tip Blunt": 0.18, # >0 verhindert Nadelspitzen (0 = spitz, 0.45 = Kaktus)
|
"Tip Blunt": 0.18, # >0 verhindert Nadelspitzen (0 = spitz, 0.45 = Kaktus)
|
||||||
|
"Crown Taper": 0.35, # >0 kegelfoermig, 0 saeulig, <0 besenfoermig
|
||||||
|
"Crown Bulge": 0.0, # >0 = Bauch in der Mitte (runde Krone)
|
||||||
"Root Flare": 1.1, # Wurzelanlauf: Stamm verbreitert sich am Fuss
|
"Root Flare": 1.1, # Wurzelanlauf: Stamm verbreitert sich am Fuss
|
||||||
"Root Lobes": 6.0, # Wurzelbretter; sollte in "Sides" aufgehen,
|
"Root Lobes": 6.0, # Wurzelbretter; sollte in "Sides" aufgehen,
|
||||||
# sonst sampelt das Profil die Lappen weg
|
# sonst sampelt das Profil die Lappen weg
|
||||||
@@ -82,6 +84,47 @@ PRESETS = {
|
|||||||
"Sub Count": 1, "Sub Length": 0.35, "Sub Up": 1.6, "Sides": 4,
|
"Sub Count": 1, "Sub Length": 0.35, "Sub Up": 1.6, "Sides": 4,
|
||||||
"Detail": 0.3, "Branch Count": 10,
|
"Detail": 0.3, "Branch Count": 10,
|
||||||
},
|
},
|
||||||
|
# --- Varianten ueber die Kronenform (Idee: modular_tree "envelope shapes") ---
|
||||||
|
"tanne": { # kegelfoermig: unten lange Aeste, oben kurz, leicht haengend
|
||||||
|
"Height": 7.0, "Trunk Radius": 0.15, "Bend": 0.15, "Taper": 0.95,
|
||||||
|
"Branch Count": 22, "Branch Length": 1.9, "Branch Up": -0.25,
|
||||||
|
"Branch Start": 0.12, "Branch End": 0.97,
|
||||||
|
"Crown Taper": 0.9, "Crown Bulge": 0.0,
|
||||||
|
"Branch Bend": 0.3, "Branch Thickness": 0.2, "Sub Count": 1,
|
||||||
|
"Sub Length": 0.4, "Root Flare": 0.7,
|
||||||
|
},
|
||||||
|
"eiche": { # runde, breite Krone: Bauch in der Mitte, dicker Stamm
|
||||||
|
"Height": 5.5, "Trunk Radius": 0.24, "Bend": 0.5, "Taper": 0.75,
|
||||||
|
"Branch Count": 10, "Branch Length": 2.2, "Branch Up": 0.9,
|
||||||
|
"Branch Start": 0.3, "Branch End": 0.95,
|
||||||
|
"Crown Taper": -0.15, "Crown Bulge": 0.5,
|
||||||
|
"Branch Bend": 0.9, "Branch Thickness": 0.4, "Sub Count": 3,
|
||||||
|
"Sub Length": 0.8, "Root Flare": 1.6, "Root Lobe Depth": 1.6,
|
||||||
|
},
|
||||||
|
"birke": { # schlank, hoher Ansatz, feine Zweige
|
||||||
|
"Height": 7.5, "Trunk Radius": 0.09, "Bend": 0.7, "Taper": 0.92,
|
||||||
|
"Branch Count": 12, "Branch Length": 1.4, "Branch Up": 1.1,
|
||||||
|
"Branch Start": 0.45, "Branch End": 0.98,
|
||||||
|
"Crown Taper": 0.1, "Crown Bulge": 0.25,
|
||||||
|
"Branch Bend": 0.8, "Branch Thickness": 0.22, "Sub Count": 3,
|
||||||
|
"Sub Length": 0.5, "Root Flare": 0.6,
|
||||||
|
},
|
||||||
|
"weide": { # haengende Zweige (Droop positiv), breit ausladend
|
||||||
|
"Height": 5.0, "Trunk Radius": 0.18, "Bend": 0.8, "Taper": 0.8,
|
||||||
|
"Branch Count": 12, "Branch Length": 2.0, "Branch Up": 0.5,
|
||||||
|
"Branch Start": 0.35, "Branch End": 0.95,
|
||||||
|
"Crown Taper": -0.2, "Crown Bulge": 0.4,
|
||||||
|
"Branch Droop": 1.2, "Branch Bend": 0.7, "Branch Thickness": 0.28,
|
||||||
|
"Sub Count": 3, "Sub Length": 0.9, "Root Flare": 1.2,
|
||||||
|
},
|
||||||
|
"toter_baum": { # knorrig, kaum Zweige, starke Kruemmung
|
||||||
|
"Height": 4.5, "Trunk Radius": 0.17, "Bend": 1.5, "Taper": 0.88,
|
||||||
|
"Branch Count": 6, "Branch Length": 1.5, "Branch Up": 0.9,
|
||||||
|
"Branch Start": 0.3, "Branch End": 0.9,
|
||||||
|
"Crown Taper": 0.3, "Crown Bulge": 0.0,
|
||||||
|
"Branch Bend": 1.4, "Branch Thickness": 0.3, "Sub Count": 1,
|
||||||
|
"Sub Length": 0.5, "Root Flare": 1.4, "Tip Blunt": 0.08,
|
||||||
|
},
|
||||||
# Kaktus: dicker, kaum verjuengter Stamm, wenige Arme, die per NEGATIVEM
|
# Kaktus: dicker, kaum verjuengter Stamm, wenige Arme, die per NEGATIVEM
|
||||||
# Droop nach oben kruemmen (Saguaro-Silhouette). Keine Sub-Aeste.
|
# Droop nach oben kruemmen (Saguaro-Silhouette). Keine Sub-Aeste.
|
||||||
"kaktus": {
|
"kaktus": {
|
||||||
@@ -179,6 +222,8 @@ def build_group():
|
|||||||
add_in("Tip Blunt", 'NodeSocketFloat', DEFAULTS["Tip Blunt"], 0.0, 0.9)
|
add_in("Tip Blunt", 'NodeSocketFloat', DEFAULTS["Tip Blunt"], 0.0, 0.9)
|
||||||
add_in("UV Scale", 'NodeSocketFloat', DEFAULTS["UV Scale"], 0.01, 20.0)
|
add_in("UV Scale", 'NodeSocketFloat', DEFAULTS["UV Scale"], 0.01, 20.0)
|
||||||
add_in("Detail", 'NodeSocketFloat', DEFAULTS["Detail"], 0.2, 2.0)
|
add_in("Detail", 'NodeSocketFloat', DEFAULTS["Detail"], 0.2, 2.0)
|
||||||
|
add_in("Crown Taper", 'NodeSocketFloat', DEFAULTS["Crown Taper"], -1.5, 1.5)
|
||||||
|
add_in("Crown Bulge", 'NodeSocketFloat', DEFAULTS["Crown Bulge"], -1.0, 2.0)
|
||||||
add_in("Root Flare", 'NodeSocketFloat', DEFAULTS["Root Flare"], 0.0, 4.0)
|
add_in("Root Flare", 'NodeSocketFloat', DEFAULTS["Root Flare"], 0.0, 4.0)
|
||||||
add_in("Root Lobes", 'NodeSocketFloat', DEFAULTS["Root Lobes"], 0.0, 12.0)
|
add_in("Root Lobes", 'NodeSocketFloat', DEFAULTS["Root Lobes"], 0.0, 12.0)
|
||||||
add_in("Root Lobe Depth", 'NodeSocketFloat', DEFAULTS["Root Lobe Depth"], 0.0, 3.0)
|
add_in("Root Lobe Depth", 'NodeSocketFloat', DEFAULTS["Root Lobe Depth"], 0.0, 3.0)
|
||||||
@@ -422,10 +467,50 @@ def build_group():
|
|||||||
pscale.inputs["To Max"].default_value = 1.0
|
pscale.inputs["To Max"].default_value = 1.0
|
||||||
pscale.clamp = True
|
pscale.clamp = True
|
||||||
|
|
||||||
|
# ---------- Kronenform (botanische Huellkurve) ----------
|
||||||
|
# Idee aus modular_tree / Weber-Penn: die Astlaenge haengt von der relativen
|
||||||
|
# Hoehe am Stamm ab. Das entscheidet die Silhouette:
|
||||||
|
# Crown Taper > 0 -> unten lang, oben kurz = kegelfoermig (Tanne)
|
||||||
|
# Crown Taper = 0 -> ueberall gleich = saeulenfoermig (Pappel)
|
||||||
|
# Crown Taper < 0 -> unten kurz, oben lang = besenfoermig
|
||||||
|
# Crown Bulge > 0 -> Maximum in der Mitte = rund (Eiche)
|
||||||
|
czp = N("GeometryNodeInputPosition"); czp.location = (750, -20)
|
||||||
|
czs = N("ShaderNodeSeparateXYZ"); czs.location = (900, -20)
|
||||||
|
L(czp.outputs[0], czs.inputs[0])
|
||||||
|
czn = N("ShaderNodeMath"); czn.location = (1050, -20); czn.operation = 'DIVIDE'
|
||||||
|
L(czs.outputs["Z"], czn.inputs[0]); L(V["Height"], czn.inputs[1])
|
||||||
|
czc = N("ShaderNodeMath"); czc.location = (1200, -20); czc.operation = 'MINIMUM'
|
||||||
|
czc.inputs[1].default_value = 1.0
|
||||||
|
L(czn.outputs[0], czc.inputs[0])
|
||||||
|
ctm = N("ShaderNodeMath"); ctm.location = (1350, -20); ctm.operation = 'MULTIPLY'
|
||||||
|
L(V["Crown Taper"], ctm.inputs[0]); L(czc.outputs[0], ctm.inputs[1])
|
||||||
|
cts = N("ShaderNodeMath"); cts.location = (1500, -20); cts.operation = 'SUBTRACT'
|
||||||
|
cts.inputs[0].default_value = 1.0
|
||||||
|
L(ctm.outputs[0], cts.inputs[1])
|
||||||
|
# Bauch in der Mitte: sin(pi * t)
|
||||||
|
cbs = N("ShaderNodeMath"); cbs.location = (1350, -180); cbs.operation = 'MULTIPLY'
|
||||||
|
cbs.inputs[1].default_value = 3.14159
|
||||||
|
L(czc.outputs[0], cbs.inputs[0])
|
||||||
|
cbi = N("ShaderNodeMath"); cbi.location = (1500, -180); cbi.operation = 'SINE'
|
||||||
|
L(cbs.outputs[0], cbi.inputs[0])
|
||||||
|
cbm = N("ShaderNodeMath"); cbm.location = (1650, -180); cbm.operation = 'MULTIPLY'
|
||||||
|
L(V["Crown Bulge"], cbm.inputs[0]); L(cbi.outputs[0], cbm.inputs[1])
|
||||||
|
cba = N("ShaderNodeMath"); cba.location = (1800, -180); cba.operation = 'ADD'
|
||||||
|
cba.inputs[0].default_value = 1.0
|
||||||
|
L(cbm.outputs[0], cba.inputs[1])
|
||||||
|
ccm = N("ShaderNodeMath"); ccm.location = (1800, -20); ccm.operation = 'MULTIPLY'
|
||||||
|
L(cts.outputs[0], ccm.inputs[0]); L(cba.outputs[0], ccm.inputs[1])
|
||||||
|
ccl = N("ShaderNodeMath"); ccl.location = (1950, -20); ccl.operation = 'MAXIMUM'
|
||||||
|
ccl.inputs[1].default_value = 0.05
|
||||||
|
L(ccm.outputs[0], ccl.inputs[0])
|
||||||
|
# mit der Elterndicken-Skalierung kombinieren
|
||||||
|
pfin = N("ShaderNodeMath"); pfin.location = (2100, 120); pfin.operation = 'MULTIPLY'
|
||||||
|
L(pscale.outputs[0], pfin.inputs[0]); L(ccl.outputs[0], pfin.inputs[1])
|
||||||
|
|
||||||
inst = N("GeometryNodeInstanceOnPoints"); inst.location = (1400, 320)
|
inst = N("GeometryNodeInstanceOnPoints"); inst.location = (1400, 320)
|
||||||
L(_out(c2p, "Points"), _sock(inst, "Points"))
|
L(_out(c2p, "Points"), _sock(inst, "Points"))
|
||||||
L(_out(bsetr, "Curve"), _sock(inst, "Instance"))
|
L(_out(bsetr, "Curve"), _sock(inst, "Instance"))
|
||||||
L(pscale.outputs[0], _sock(inst, "Scale"))
|
L(pfin.outputs[0], _sock(inst, "Scale"))
|
||||||
if align is not None:
|
if align is not None:
|
||||||
L(align.outputs[0], _sock(inst, "Rotation"))
|
L(align.outputs[0], _sock(inst, "Rotation"))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user