From f9e3fe4223b287694eff268841521bddfa777a84 Mon Sep 17 00:00:00 2001 From: D4rkst3r Date: Wed, 29 Jul 2026 10:33:09 +0200 Subject: [PATCH] Tree Generator v1.1.0: Aeste folgen der Elternkurve Kern aus EcoGame tools/blender_tree_gen.py regeneriert. Ast-Richtung jetzt ueber Tangent/Normal von 'Curve to Points' (Goldener Winkel) statt Weltkoordinaten -> Sub-Aeste wachsen entlang ihres Elternastes statt quer dazu. 'Tip Blunt' neu. Headless getestet: alle 4 Presets, Stufen aufsteigend, Modifier-Apply ok. Co-Authored-By: Claude Opus 4.8 --- README.md | 5 +++ blender_manifest_tree.toml | 2 +- dist/index.json | 8 ++-- dist/stylized_tree_generator-1.0.0.zip | Bin 9292 -> 0 bytes dist/stylized_tree_generator-1.1.0.zip | Bin 0 -> 9492 bytes stylized_tree_generator.py | 56 ++++++++++++++----------- 6 files changed, 42 insertions(+), 29 deletions(-) delete mode 100644 dist/stylized_tree_generator-1.0.0.zip create mode 100644 dist/stylized_tree_generator-1.1.0.zip diff --git a/README.md b/README.md index 467ae08..2708624 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,11 @@ Gruppe. Blaetter/Krone macht man selbst — das Addon liefert die Struktur. im Viewport ziehen, der Baum aktualisiert sich sofort. - **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). + ⚠️ **Bekannte Grenze:** Das `kaktus`-Preset ist noch nicht ueberzeugend — die Arme spreizen im V, statt nach dem Abgang senkrecht hochzulaufen (die Droop-Naeherung kann nur einen gleichmaessigen Bogen, keinen Ellbogen). Als Platzhalter brauchbar. diff --git a/blender_manifest_tree.toml b/blender_manifest_tree.toml index cf5e935..1d0df9f 100644 --- a/blender_manifest_tree.toml +++ b/blender_manifest_tree.toml @@ -1,7 +1,7 @@ schema_version = "1.0.0" id = "stylized_tree_generator" -version = "1.0.0" +version = "1.1.0" name = "Stylized Tree Generator" tagline = "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen" maintainer = "D4rkst3r" diff --git a/dist/index.json b/dist/index.json index 1f3679c..6171214 100644 --- a/dist/index.json +++ b/dist/index.json @@ -32,7 +32,7 @@ "id": "stylized_tree_generator", "name": "Stylized Tree Generator", "tagline": "Parametrische Baeume, Palmen, Bueschen mit Wachstums-Stufen", - "version": "1.0.0", + "version": "1.1.0", "type": "add-on", "maintainer": "D4rkst3r", "license": [ @@ -48,9 +48,9 @@ "Mesh", "Modeling" ], - "archive_url": "./stylized_tree_generator-1.0.0.zip", - "archive_size": 9292, - "archive_hash": "sha256:23693ed0476102b52d76e67d1d711ce6c55925b47c9323a06d535e51a2508c01" + "archive_url": "./stylized_tree_generator-1.1.0.zip", + "archive_size": 9492, + "archive_hash": "sha256:e563fd7c056b20c3d20c779713b5891baf7843f5158e4276629b8886f1efbd9f" } ] } \ No newline at end of file diff --git a/dist/stylized_tree_generator-1.0.0.zip b/dist/stylized_tree_generator-1.0.0.zip deleted file mode 100644 index 527ac12a6077d15c08a63a112c4a83a106835ad2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9292 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 literal 0 HcmV?d00001 diff --git a/stylized_tree_generator.py b/stylized_tree_generator.py index 226775a..000d0c5 100644 --- a/stylized_tree_generator.py +++ b/stylized_tree_generator.py @@ -1,7 +1,7 @@ bl_info = { "name": "Stylized Tree Generator", "author": "D4rkst3r", - "version": (1, 0, 0), + "version": (1, 1, 0), "blender": (4, 2, 0), "location": "View3D > Sidebar > Tree Gen", "description": "Parametrischer Baum-/Palmen-/Busch-Generator (Geometry Nodes) mit Wachstums-Stufen", @@ -44,6 +44,7 @@ DEFAULTS = { "Sub Length": 0.55, "Sub Up": 1.4, "Sides": 6, + "Tip Blunt": 0.0, # 0 = laeuft spitz aus (Baum), 0.45 = stumpfes Ende (Kaktus) "Ribs": 0.0, # senkrechte Kanneluren (0 = glatt); Kaktus ~9 "Rib Depth": 0.0, } @@ -77,6 +78,7 @@ PRESETS = { "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, "Sides": 18, "Ribs": 9.0, "Rib Depth": 0.09, }, } @@ -145,6 +147,7 @@ def build_group(): 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) + add_in("Tip Blunt", 'NodeSocketFloat', DEFAULTS["Tip Blunt"], 0.0, 0.9) add_in("Ribs", 'NodeSocketFloat', DEFAULTS["Ribs"], 0.0, 20.0) add_in("Rib Depth", 'NodeSocketFloat', DEFAULTS["Rib Depth"], 0.0, 0.5) @@ -222,8 +225,8 @@ def build_group(): # egal wie fein resampled wird. Mit Mindestradius + Fill Caps endet # der Arm stumpf/gerundet statt als Dorn. mx = N("ShaderNodeMath"); mx.location = (x + 450, y); mx.operation = 'MAXIMUM' - mx.inputs[1].default_value = 0.45 L(rt.outputs[0], mx.inputs[0]) + L(V["Tip Blunt"], mx.inputs[1]) return mx tdome = _dome(spar, -900, 220) @@ -285,19 +288,33 @@ def build_group(): L(_out(bres, "Curve"), _sock(bsetr, "Curve")) L(bscl.outputs[0], _sock(bsetr, "Radius")) + # ---------- Ausrichtung relativ zur ELTERNKURVE ---------- + # Curve to Points liefert Tangent + Normal des Ansatzpunktes gratis mit. + # Die Normale um die Tangente zu drehen (Index * Goldener Winkel) verteilt + # die Aeste spiralig um den Elternast (Phyllotaxis) UND folgt automatisch + # dessen Biegung. Vorher wurde die Richtung aus Weltkoordinaten gerechnet -> + # Aeste standen wie angeklebte Nadeln quer zum Ast. + def _child_dir(points_node, up_socket, x, y): + i = N("GeometryNodeInputIndex"); i.location = (x, y + 220) + a = N("ShaderNodeMath"); a.location = (x + 150, y + 220); a.operation = 'MULTIPLY' + a.inputs[1].default_value = 2.399963 # Goldener Winkel + L(i.outputs[0], a.inputs[0]) + vr = N("ShaderNodeVectorRotate"); vr.location = (x + 320, y + 120) + vr.rotation_type = 'AXIS_ANGLE' + L(_out(points_node, "Normal"), vr.inputs["Vector"]) + L(_out(points_node, "Tangent"), vr.inputs["Axis"]) + L(a.outputs[0], vr.inputs["Angle"]) + lean = N("ShaderNodeVectorMath"); lean.location = (x + 320, y - 60) + lean.operation = 'SCALE' + L(_out(points_node, "Tangent"), lean.inputs[0]) + L(up_socket, _sock(lean, "Scale")) + add = N("ShaderNodeVectorMath"); add.location = (x + 500, y + 40) + add.operation = 'ADD' + L(vr.outputs[0], add.inputs[0]); L(lean.outputs[0], add.inputs[1]) + return add + # ---------- radiale Ausrichtung je Ast ---------- - idx = N("GeometryNodeInputIndex"); idx.location = (100, 560) - frac = N("ShaderNodeMath"); frac.location = (260, 560); frac.operation = 'DIVIDE' - L(idx.outputs[0], frac.inputs[0]); L(V["Branch Count"], frac.inputs[1]) - ang = N("ShaderNodeMath"); ang.location = (420, 560); ang.operation = 'MULTIPLY' - ang.inputs[1].default_value = 6.283185 - L(frac.outputs[0], ang.inputs[0]) - cs = N("ShaderNodeMath"); cs.location = (580, 620); cs.operation = 'COSINE' - sn = N("ShaderNodeMath"); sn.location = (580, 500); sn.operation = 'SINE' - L(ang.outputs[0], cs.inputs[0]); L(ang.outputs[0], sn.inputs[0]) - dirv = N("ShaderNodeCombineXYZ"); dirv.location = (740, 560) - L(cs.outputs[0], dirv.inputs["X"]); L(sn.outputs[0], dirv.inputs["Y"]) - L(V["Branch Up"], dirv.inputs["Z"]) + dirv = _child_dir(c2p, V["Branch Up"], 100, 560) align = _new_any("FunctionNodeAlignRotationToVector", "FunctionNodeAlignEulerToVector") if align is not None: @@ -402,16 +419,7 @@ def build_group(): L(srad2.outputs[0], _sock(ssetr, "Radius")) # Richtung: radial gestreut (Index) + "Sub Up" - sidx = N("GeometryNodeInputIndex"); sidx.location = (2100, 1060) - sfr = N("ShaderNodeMath"); sfr.location = (2250, 1060); sfr.operation = 'MULTIPLY' - sfr.inputs[1].default_value = 2.399963 # Goldener Winkel -> gute Streuung - L(sidx.outputs[0], sfr.inputs[0]) - scs = N("ShaderNodeMath"); scs.location = (2400, 1120); scs.operation = 'COSINE' - ssn = N("ShaderNodeMath"); ssn.location = (2400, 1000); ssn.operation = 'SINE' - L(sfr.outputs[0], scs.inputs[0]); L(sfr.outputs[0], ssn.inputs[0]) - sdir = N("ShaderNodeCombineXYZ"); sdir.location = (2550, 1060) - L(scs.outputs[0], sdir.inputs["X"]); L(ssn.outputs[0], sdir.inputs["Y"]) - L(V["Sub Up"], sdir.inputs["Z"]) + sdir = _child_dir(sp, V["Sub Up"], 2100, 1060) salign = _new_any("FunctionNodeAlignRotationToVector", "FunctionNodeAlignEulerToVector") if salign is not None: