Tree Generator v1.12.0: Gabelung statt Nadeln, Droop-Kurve regelbar

- 'Sub Start'/'Sub End' + hoeheres 'Sub Up': Zweige folgen ihrem Elternast und
  bilden Y-Gabelungen (Weber-Penn "split") statt seitlich abzustehen
- 'Droop Curve': 2 = weicher Bogen (Palme), 4+ = scharfer Ellbogen (Kaktus)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 11:37:52 +02:00
co-authored by Claude Opus 4.8
parent d9c642fcd2
commit 794ed4ba38
5 changed files with 28 additions and 16 deletions
+23 -11
View File
@@ -1,7 +1,7 @@
bl_info = {
"name": "Stylized Tree Generator",
"author": "D4rkst3r",
"version": (1, 10, 0),
"version": (1, 12, 0),
"blender": (4, 2, 0),
"location": "View3D > Sidebar > Tree Gen",
"description": "Parametrischer Baum-/Palmen-/Busch-Generator (Geometry Nodes) mit Wachstums-Stufen",
@@ -38,11 +38,14 @@ DEFAULTS = {
"Branch End": 0.95,
"Branch Bend": 0.75, # Krummheit je Ast/Zweig (0 = gerade Staebe)
"Branch Droop": 0.0, # >0 haengt nach unten (Palme), <0 kruemmt nach oben (Kaktus)
"Droop Curve": 2.0, # 2 = weicher Bogen, 4+ = scharfer Ellbogen
"Branch Thickness": 0.32, # Ast-Dicke relativ zum Stamm
"Branch Taper": 0.55, # schwach verjuengen -> Roehre statt Kegel/Dorn
"Sub Count": 2, # Sub-Aeste je Hauptast (0 = aus)
"Sub Start": 0.45, # Ansatzbereich der Zweige am Ast ...
"Sub End": 0.95, # ... nahe 1.0 + hohes Sub Up = Gabelung
"Sub Length": 0.55,
"Sub Up": 1.4,
"Sub Up": 2.2, # hoch = Zweig folgt dem Ast (Gabel statt Nadel)
"Sides": 12, # Stamm rund genug fuer die Wurzelbretter
# (+104 Tris ggue. 8 - gemessen, lohnt sich)
"Branch Sides": 4, # Aeste sparsamer
@@ -129,14 +132,15 @@ PRESETS = {
# Droop nach oben kruemmen (Saguaro-Silhouette). Keine Sub-Aeste.
"kaktus": {
"Height": 3.0, "Trunk Radius": 0.28, "Bend": 0.08, "Taper": 0.10,
"Branch Count": 2, "Branch Length": 1.6, "Branch Up": 0.05,
"Branch Start": 0.28, "Branch End": 0.5,
"Branch Count": 2, "Branch Length": 1.9, "Branch Up": 0.12,
"Branch Start": 0.30, "Branch End": 0.46,
"Branch Bend": 0.0,
"Branch Droop": -2.2, # negativ = Arme kruemmen nach OBEN (Saguaro)
"Branch Droop": -3.0, # negativ = Arme kruemmen nach OBEN (Saguaro)
"Droop Curve": 4.5, # spaeter, dafuer scharfer Ellbogen
"Branch Thickness": 0.72, # Arme fast so dick wie der Stamm
"Branch Taper": 0.12, # Arme bleiben dick statt spitz zuzulaufen
"Sub Count": 0,
"Tip Blunt": 0.45,
"Sub Count": 0, "Crown Taper": 0.0, "Root Flare": 0.25,
"Root Lobe Depth": 0.0, "Tip Blunt": 0.45,
"Sides": 16, "Branch Sides": 12, "Ribs": 9.0, "Rib Depth": 0.09,
},
}
@@ -211,9 +215,12 @@ def build_group():
# Droop darf NEGATIV sein: dann kruemmen sich die Aeste nach OBEN
# (= Kaktus-Arme statt Palmwedel).
add_in("Branch Droop", 'NodeSocketFloat', DEFAULTS["Branch Droop"], -3.0, 3.0)
add_in("Droop Curve", 'NodeSocketFloat', DEFAULTS["Droop Curve"], 1.0, 8.0)
add_in("Branch Thickness", 'NodeSocketFloat', DEFAULTS["Branch Thickness"], 0.05, 1.0)
add_in("Branch Taper", 'NodeSocketFloat', DEFAULTS["Branch Taper"], 0.0, 1.0)
add_in("Sub Count", 'NodeSocketInt', DEFAULTS["Sub Count"], 0, 12)
add_in("Sub Start", 'NodeSocketFloat', DEFAULTS["Sub Start"], 0.0, 1.0)
add_in("Sub End", 'NodeSocketFloat', DEFAULTS["Sub End"], 0.0, 1.0)
add_in("Sub Length", 'NodeSocketFloat', DEFAULTS["Sub Length"], 0.05, 5.0)
add_in("Sub Up", 'NodeSocketFloat', DEFAULTS["Sub Up"], -3.0, 3.0)
add_in("Sides", 'NodeSocketInt', DEFAULTS["Sides"], 3, 32)
@@ -543,8 +550,10 @@ def build_group():
L(rfac.outputs[0], _sock(rscale, "Scale"))
# Droop: Spitzen haengen nach unten (Palmwedel) -- quadratisch = schoene Kurve
dsq = N("ShaderNodeMath"); dsq.location = (1350, -320); dsq.operation = 'MULTIPLY'
L(rspar.outputs["Factor"], dsq.inputs[0]); L(rspar.outputs["Factor"], dsq.inputs[1])
# Droop-Kurve: Exponent 2 = weicher Bogen (Palmwedel), hoeher = der Arm
# bleibt erst flach und knickt dann scharf ab (Saguaro-Ellbogen).
dsq = N("ShaderNodeMath"); dsq.location = (1350, -320); dsq.operation = 'POWER'
L(rspar.outputs["Factor"], dsq.inputs[0]); L(V["Droop Curve"], dsq.inputs[1])
dmul = N("ShaderNodeMath"); dmul.location = (1500, -320); dmul.operation = 'MULTIPLY'
L(V["Branch Droop"], dmul.inputs[0]); L(dsq.outputs[0], dmul.inputs[1])
dneg = N("ShaderNodeMath"); dneg.location = (1650, -320); dneg.operation = 'MULTIPLY'
@@ -567,9 +576,12 @@ def build_group():
# Curve to Points keine Punkte -> es entsteht schlicht nichts (kein Fehler).
strim = N("GeometryNodeTrimCurve"); strim.location = (2100, 520)
L(_out(rsetp, "Geometry"), _sock(strim, "Curve"))
# Wo am Elternast die Zweige sitzen. Nahe 1.0 zusammengedraengt + hohes
# "Sub Up" ergibt eine GABELUNG (Weber-Penn "split") statt seitlicher
# Kinder - das ist der Unterschied zwischen "Stab mit Nadeln" und Geaest.
try:
_sock(strim, "Start").default_value = 0.3
_sock(strim, "End").default_value = 0.9
L(V["Sub Start"], _sock(strim, "Start"))
L(V["Sub End"], _sock(strim, "End"))
except KeyError:
pass
sp = N("GeometryNodeCurveToPoints"); sp.location = (2250, 520)