Tree Gen 1.36.0: Ursprung an der Stammbasis, Weide gedeckelt, Birke ueberarbeitet

1) Ursprung: Stammbasis statt tiefstem Slot-0-Punkt
   Zweimal war das schon "behoben". Erst kam der Ursprung aus der Gesamt-Bbox
   (eine Blatt-Card hob den Baum an), dann aus Material-Slot 0 - aber die AESTE
   gehoeren ebenfalls zum Rinden-Slot. Gemessen an Tanne_01_S1: tiefster
   Slot-0-Punkt -5.35 cm, tiefster STAMM-Punkt -0.02 cm. Die Stammbasis
   schwebte 5.3 cm ueber dem Boden.

   Die exakte Trennung liefert ast_id (0 = Stamm) - dasselbe Attribut, das der
   Baum fuer die Faell-Teile ohnehin traegt. Ein Schwellwert auf den
   Achsabstand faellt beim Kaktus um: dessen Stamm ist dicker als jeder
   sinnvolle Schwellwert. X/Y kommt jetzt aus dem untersten RING statt aus der
   Stamm-Bbox; bei Bend 1.5 liegt die Bbox-Mitte in der Kruemmung.

   Neu: tests/test_ursprung.py, gemessen am reimportierten FBX. Die erste
   Fassung des Tests suchte den "tiefsten Punkt nahe der Achse" - die
   Gegenprobe hat sie umgeworfen, weil bei der Tanne eine Astspitze ins
   Achsband faellt. Ein Schwellwert, der die Bugfassung durchlaesst, prueft
   nichts. Jetzt wird ein Stammquerschnitt gesucht: Vertices, die die Achse in
   allen Himmelsrichtungen umschliessen. Gegenprobe bestanden.

   Nebenbefund: ein Baum ohne Aeste traegt gar kein ast_id (Branch Count 0
   schaltet den Ast-Zweig des Graphen ab). Dann ist alles Stamm und der
   Fallback exakt.

2) Weide S4 auf 350 Cards gedeckelt - Entscheidung des Users
   Gemessen 5456-5594 Tris ueber drei Seeds gegen 4300 Budget; nach der
   Deckelung 3890-3962. LEAF_STUFEN_PRESET haelt solche Ausnahmen je Preset.

3) Birke war eine Saeule
   Gemessen B/H 0.15 - schmaler als der Standardbaum (0.22), nicht die Haelfte
   der Eiche (0.36). Ursache: Branch Up 1.1, die Aeste klebten am Stamm.
   Zielband 0.35-0.55 aus Van den Berk (8-12 m bei 15-20 m) und Woodland Trust
   (6-10 m bei 15-25 m); jetzt 0.51.

   Haengende Zweigenden ueber Branch Droop 0.8 + Droop Curve 3.5, nicht ueber
   negatives Sub Up: das wurde von +2.2 bis -2.0 durchgemessen und bewegt
   nichts (1-6 %), weil die Sub-Aeste zu kurz sind. Mit Droop 26 % bei einem
   Fall von 0.033 x Hoehe - wie die Tanne (0.030), weit weg von der Weide
   (0.213).

4) run_tests.ps1 benennt Blender-Abstuerze
   test_export_robust starb rund in jedem sechsten Lauf mit
   EXCEPTION_ACCESS_VIOLATION und der Runner meldete "<keine Ergebniszeile>".
   Der Stack enthaelt keinen einzigen Addon-Frame (RNA_property_int_get ->
   rna_property_rna_or_id_get -> IDP_GetPropertyFromGroup, Null-Deref), und mit
   eingebauten Markern verschwindet der Absturz: Heisenbug in Blender 5.1.2.
   Der Runner wiederholt jetzt einmal und benennt den Absturz.

24 Tests bestehen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-06 11:55:34 +02:00
co-authored by Claude Opus 4.8
parent fa7067d42e
commit 499d507e28
9 changed files with 461 additions and 37 deletions
+27 -1
View File
@@ -23,15 +23,38 @@ $tests = Get-ChildItem (Join-Path $root "tests") -Filter "test_$Filter.py" | Sor
if (-not $tests) { throw "Keine Tests gefunden fuer Filter '$Filter'" }
$failed = @()
$abgestuerzt = @()
foreach ($t in $tests) {
# Ein Lauf kann an einem BLENDER-ABSTURZ sterben statt an einem Testfehler.
# Nachgemessen an test_export_robust: rund jeder sechste Lauf endet mit
# EXCEPTION_ACCESS_VIOLATION - und zwar ohne einen einzigen Addon-Frame im
# Stack (RNA_property_int_get -> rna_property_rna_or_id_get ->
# IDP_GetPropertyFromGroup, Null-Deref beim Lesen einer Integer-Property).
# Baut man Marker in denselben Test ein, verschwindet der Absturz: ein
# Heisenbug, also Blender 5.1.2 und nicht unser Code. Wenn der Lauf
# durchlaeuft, bestehen ALLE Checks des Tests.
# Deshalb einmal wiederholen und den Absturz benennen, statt ihn als
# stillen Testfehler auszugeben - "<keine Ergebniszeile>" hat monatelang
# niemandem gesagt, was eigentlich los war.
$out = & $Blender --background --factory-startup --python $t.FullName 2>&1 | Out-String
$crash = $false
if ($out -match "EXCEPTION_ACCESS_VIOLATION") {
$crash = $true
$out = & $Blender --background --factory-startup --python $t.FullName 2>&1 | Out-String
$abgestuerzt += if ($out -match "EXCEPTION_ACCESS_VIOLATION") {
$t.BaseName + " (auch im zweiten Lauf)"
} else { $t.BaseName }
}
# Die Tests melden ihr Ergebnis als letzte Zeile mit "ERGEBNIS:" bzw.
# "Alle Checks bestanden." - alles andere ist Blender-Rauschen.
$line = ($out -split "`n" |
Where-Object { $_ -match "ERGEBNIS|Alle Checks bestanden|FEHLGESCHLAGEN" } |
Select-Object -Last 1)
if (-not $line) { $line = "<keine Ergebniszeile>" }
if (-not $line) {
$line = if ($crash) { "<Blender abgestuerzt, auch im zweiten Lauf>" }
else { "<keine Ergebniszeile>" }
}
$line = $line.Trim()
$ok = ($line -match "ALLE|OK$|bestanden") -and ($line -notmatch "FEHLER|FEHLGESCHLAGEN")
@@ -42,6 +65,9 @@ foreach ($t in $tests) {
}
Write-Host ""
if ($abgestuerzt) {
Write-Host ("Blender-Absturz (wiederholt): {0}" -f ($abgestuerzt -join ", ")) -ForegroundColor Yellow
}
if ($failed) {
Write-Host ("FEHLGESCHLAGEN ({0}): {1}" -f $failed.Count, ($failed -join ", ")) -ForegroundColor Red
exit 1