Tree Gen 1.33.0: Hoehen-Filter - der Setzling bekommt einen freien Fuss
Befund aus der Turnhalle: die Setzlings-Blaetter verteilen sich ueber die ganze
Stammhoehe, es entsteht eine belaubte Saeule statt einer Krone. Nachgemessen:
44 % der Cards sassen unter 40 % der Baumhoehe, die tiefste bei 6 %.
Der Radius-Filter kann das nicht loesen - er trennt duenn von dick, aber ein
junger Stamm ist UEBERALL duenn. Also ein zweiter Filter ueber die Hoehe: Laub
erst ab dem Kronenansatz, als Anteil der Baumhoehe. Die Schwelle kommt aus der
Bounding Box des Baums, nicht als Meterwert - fest waere sie beim Setzling die
halbe Pflanze und beim Altbaum wirkungslos.
Kronenansatz je Stufe (LEAF_STUFEN): S1 40 %, S2 35 %, S3 30 %, S4 25 %.
unter Ansatz tiefste Card
vorher nachher vorher nachher
S1 44 % 0 % 6 % 46 %
S2 32 % 0 % 24 % 36 %
S3 9 % 0 % 31 % 34 %
S4 3 % 0 % 34 % 34 % (unveraendert)
Beim Altbaum ist der Filter praktisch ein Sicherheitsnetz - dort sitzt ohnehin
nichts tief, genau wie gemeldet.
Dichte von S1/S2 nachgezogen: der Filter nimmt dem Setzling sonst die Haelfte
der Cards (9 -> 4), weil dessen Laub vorher ueber die ganze Stammhoehe verteilt
war. Jetzt 11 Cards bei S1, und 486 Tris gegen 800 Budget.
23 Tests bestehen (Suite zweimal durchlaufen).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -52,8 +52,8 @@ if not (130.0 <= s.leaf_density <= 200.0):
|
||||
% s.leaf_density)
|
||||
# Die Deckung steht als Tabelle pro Stufe, nicht als Formel. Card-ANZAHL muss
|
||||
# ueber die Stufen steigen, Card-Groesse auch.
|
||||
_d0, _g0 = tg._stufen_anteile(0.0)
|
||||
_d1, _g1 = tg._stufen_anteile(1.0)
|
||||
_d0, _g0, _h0 = tg._stufen_anteile(0.0)
|
||||
_d1, _g1, _h1 = tg._stufen_anteile(1.0)
|
||||
if _g0 >= _g1:
|
||||
fails.append("Groessen-Anteil steigt nicht ueber die Stufen (%.2f -> %.2f)"
|
||||
% (_g0, _g1))
|
||||
@@ -193,6 +193,61 @@ if kanten and kanten[0] > 0:
|
||||
"steht auf %.0f%% - die Wachstums-Kopplung greift nicht"
|
||||
% (100 * anteil, 100 * s.leaf_size_growth))
|
||||
|
||||
# --- 3a) Hoehen-Filter: der Fuss bleibt frei -----------------------------
|
||||
# Der Radius-Filter allein reicht nicht. Er trennt duenn von dick, aber ein
|
||||
# junger Stamm ist UEBERALL duenn - gemessen sassen beim Setzling 44 % der
|
||||
# Cards unter 40 % der Hoehe, die tiefste bei 6 %. Das ergibt eine belaubte
|
||||
# Saeule statt einer Krone. Der Hoehen-Filter setzt den Kronenansatz je Stufe.
|
||||
print("")
|
||||
print("%-18s %7s %6s %11s %11s" % ("Stufe", "Hoehe", "Cards", "unter Ansatz",
|
||||
"tiefste Card"))
|
||||
for st in staemme:
|
||||
bl = bpy.data.objects.get(st.name + "_Leaf")
|
||||
if bl is None:
|
||||
continue
|
||||
zs = [v.co.z for v in st.data.vertices]
|
||||
z0, h = min(zs), max(zs) - min(zs)
|
||||
gt = float(st.get("growth_t", 1.0))
|
||||
_, _, ansatz = tg._stufen_anteile(gt)
|
||||
|
||||
dg = bpy.context.evaluated_depsgraph_get()
|
||||
ev = bl.evaluated_get(dg)
|
||||
m = ev.to_mesh()
|
||||
# Card-Mitten ueber die Face-Gruppen (die Testkarte hat 2 Faces je Card)
|
||||
proc = 2
|
||||
mitten = []
|
||||
for i in range(0, len(m.polygons), proc):
|
||||
gruppe = m.polygons[i:i + proc]
|
||||
mitten.append(sum(p.center.z for p in gruppe) / len(gruppe))
|
||||
ev.to_mesh_clear()
|
||||
if not mitten:
|
||||
continue
|
||||
|
||||
unter = 100.0 * sum(1 for z in mitten if (z - z0) / h < ansatz) / len(mitten)
|
||||
tiefste = 100.0 * (min(mitten) - z0) / h
|
||||
print("%-18s %7.2f %6d %9.0f%% %10.0f%%"
|
||||
% (st.name, h, len(mitten), unter, tiefste))
|
||||
|
||||
# Ein paar Prozent Toleranz: die Card-Mitte darf leicht unter den Ansatz
|
||||
# rutschen, weil die Card um ihren Punkt herum sitzt.
|
||||
if unter > 15.0:
|
||||
fails.append("%s: %.0f%% der Cards unter dem Kronenansatz (%.0f%% der "
|
||||
"Hoehe) - der Fuss ist belaubt" % (st.name, unter,
|
||||
100 * ansatz))
|
||||
if tiefste < ansatz * 100 * 0.7:
|
||||
fails.append("%s: tiefste Card bei %.0f%% der Hoehe, Kronenansatz liegt "
|
||||
"bei %.0f%% - Laub klebt am Stamm"
|
||||
% (st.name, tiefste, 100 * ansatz))
|
||||
|
||||
# Der Ansatz muss beim Setzling HOEHER liegen als beim Altbaum: dessen
|
||||
# Verteilung passt schon von selbst, der Setzling braucht die Hilfe.
|
||||
_, _, a_jung = tg._stufen_anteile(0.0)
|
||||
_, _, a_alt = tg._stufen_anteile(1.0)
|
||||
print("Kronenansatz: S1 %.0f%%, S4 %.0f%%" % (100 * a_jung, 100 * a_alt))
|
||||
if a_jung <= a_alt:
|
||||
fails.append("Kronenansatz beim Setzling (%.2f) nicht hoeher als beim "
|
||||
"Altbaum (%.2f)" % (a_jung, a_alt))
|
||||
|
||||
# --- 3b) Budget je Stufe statt global -----------------------------------
|
||||
print("")
|
||||
print("%-18s %6s %8s %8s" % ("Stufe", "t", "Tris", "Budget"))
|
||||
|
||||
Reference in New Issue
Block a user