Panel-Umbau
-----------
Jedes Addon hatte seine Einstellungen als Kette dauerhaft offener Boxen - beim
Rock Generator 15 Stueck, man musste am ganzen Panel vorbeiscrollen, um an den
Erzeugen-Knopf zu kommen. Jetzt steht oben nur, was man bei jedem Asset anfasst
(Vorlage, Name, grosser Erzeugen-Knopf, Zufall), der Rest liegt in nummerierten,
eingeklappten Unter-Panels in der Reihenfolge des Arbeitsablaufs:
Rock Gen 9 Unter-Panels (Benennung ... Textur-Bake)
Tree Gen 4 (Wachstum, Blattwerk, Zusatz-Ebenen, Export)
Grass Gen 4 (Form, Haltung, Batch, Kanal-Belegung)
Asset Utils 5 (war schon so, dient als Vorlage)
Schalter, die ein ganzes Unter-Panel steuern (Vertex-Farben backen,
Wachstums-Stufen), sitzen jetzt als Haekchen im Panel-Kopf - Zustand sichtbar
ohne aufzuklappen.
Gemessen statt geglaubt: test_panels.py registriert alle vier Addons, laesst
jedes Panel zeichnen, prueft Tab-Zugehoerigkeit und Auf-/Zugeklappt-Absicht,
dass jeder angebotene Operator existiert - und vor allem, dass JEDE definierte
Property irgendwo erreichbar bleibt (Zweige wie base_shape='BOX' werden dabei
durchgeschaltet). Ergebnis: 0 von 122 Properties beim Umbau verloren.
Test-Suite
----------
Beim Gegenpruefen kam heraus, dass fuenf Tests still veraltet waren und eine
echte Regression nicht gemeldet haetten:
test_rock_gen suchte Objekte mit Praefix "Rock_" - die heissen seit dem
Benennungssystem "Fels_A_M_01". Fand 0 von 3.
test_base_shapes loeschte am Schleifenanfang ALLE Objekte, auch die eigenen
Kopien aus vorigen Durchlaeufen -> StructRNA removed.
test_ecogame_tree erwartete eine feste Namensliste ohne die spaeter
dazugekommenen _Leaf-Objekte.
test_tree_addon dito, ausserdem Zip-Version 1.22.0 fest verdrahtet.
test_leaves Zip-Version 1.23.0 fest verdrahtet.
Drei Muster vermieden statt nur die Symptome geflickt: neue Objekte ueber die
Differenz vorher/nachher finden statt ueber ein Namens-Praefix, Zips per glob
statt mit fester Version, Zusatz-Ebenen beim Zaehlen herausfiltern.
Neu: run_tests.ps1 faehrt die komplette Suite mit einem Befehl (-Filter fuer
einzelne). Genau das fehlte - deshalb war das Veralten nicht aufgefallen.
13 von 13 Tests bestehen.
Nebenbei
--------
build.ps1 ruft server-generate jetzt mit --html auf (browsbare index.html fuer
statisches Hosting). Nachgemessen und im README festgehalten: zwei Zips
derselben Extension-ID sind KEIN Versions-Archiv - server-generate warnt
("archive found with duplicates ... conflicting blender versions"), mehrere
Versionen einer ID gehen nur bei verschiedenen Blender-Bereichen.
Versionen: Rock 2.13.0, Tree 1.24.0, Grass 1.1.0, Asset Utils 1.1.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
2.1 KiB
Python
44 lines
2.1 KiB
Python
import bpy, sys, importlib.util
|
|
ADDON=r"A:\eco\stylized_rock_generator\stylized_tree_generator.py"
|
|
spec=importlib.util.spec_from_file_location("stg",ADDON)
|
|
m=importlib.util.module_from_spec(spec); sys.modules["stg"]=m; spec.loader.exec_module(m)
|
|
try: m.unregister()
|
|
except Exception: pass
|
|
m.register()
|
|
fails=[]
|
|
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
|
s=bpy.context.scene.tree_gen_settings
|
|
|
|
print("LIGHTMAP-Default aus:", not m.TreeGenSettings.bl_rna.properties['generate_lightmap_uv'].default)
|
|
if m.TreeGenSettings.bl_rna.properties['generate_lightmap_uv'].default: fails.append("lightmap_default")
|
|
|
|
# Wachstums-Stufen mit Art-Name
|
|
s.preset='birke'; s.art_name="Birke"; s.variant=1
|
|
s.use_growth=True; s.stages=4; s.apply_modifier=False
|
|
bpy.ops.object.treegen_create()
|
|
# Seit der Blattwerk-Ebene entsteht zu jeder Stufe ein zweites Objekt "_Leaf".
|
|
# Deshalb Stamm und Ebene getrennt pruefen statt eine feste Gesamtliste.
|
|
names=sorted(o.name for o in bpy.context.scene.objects if o.type=='MESH')
|
|
print("STUFEN:", names)
|
|
stems=[n for n in names if not n.endswith(("_Leaf","_Frucht"))]
|
|
if stems != ["Birke_01_S1","Birke_01_S2","Birke_01_S3","Birke_01_S4"]: fails.append("stufen_namen")
|
|
if [n for n in names if n.endswith("_Leaf")] != [s_+"_Leaf" for s_ in stems]: fails.append("stufen_leaf")
|
|
|
|
# Einzelbaum, Art aus Preset abgeleitet
|
|
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
|
s.use_growth=False; s.art_name=""; s.preset='eiche'; s.variant=2
|
|
bpy.ops.object.treegen_create()
|
|
single=sorted(o.name for o in bpy.context.scene.objects if o.type=='MESH')
|
|
print("EINZELN:", single)
|
|
if [n for n in single if not n.endswith(("_Leaf","_Frucht"))] != ["Eiche_02"]: fails.append("einzel_name")
|
|
|
|
# Ursprung unten-mittig + echte Meter
|
|
ob=bpy.context.scene.objects[single[0]]
|
|
ev=ob.evaluated_get(bpy.context.evaluated_depsgraph_get())
|
|
zs=[v.co.z for v in ev.data.vertices]
|
|
print("URSPRUNG z=%.3f min_z=%.3f Hoehe=%.2f m" % (ob.location.z, min(zs), max(zs)-min(zs)))
|
|
if abs(min(zs)) > 0.02: fails.append("ursprung")
|
|
m.unregister()
|
|
print("ERGEBNIS:", "ALLE CHECKS OK" if not fails else "FEHLER: "+", ".join(fails))
|
|
sys.exit(1 if fails else 0)
|