diff --git a/BlenderPanel/vfxreview_submit.py b/BlenderPanel/vfxreview_submit.py index e6ca717..1530fc2 100644 --- a/BlenderPanel/vfxreview_submit.py +++ b/BlenderPanel/vfxreview_submit.py @@ -1,7 +1,7 @@ bl_info = { "name": "VFXReview — Submit Render", "author": "Two Tales", - "version": (1, 0, 1), + "version": (1, 0, 2), "blender": (3, 6, 0), "location": "Properties > Output > VFXReview", "description": "Queue this .blend on the studio render farm instead of rendering locally", @@ -101,12 +101,28 @@ def api_request(path, payload=None, method="GET"): _project_cache = [] +# Blender does not copy the strings an EnumProperty callback returns — Python +# must keep a reference to them or the UI renders freed memory, which shows up +# as garbled labels rather than as a crash. So the items are built once when the +# project list changes and held here; the callback only ever returns this list. +_enum_items = [("", "Refresh projects...", "")] + + +def rebuild_enum_items(): + global _enum_items + if _project_cache: + _enum_items = [ + (p["code"], "%s - %s" % (p["code"], p["name"]), "") + for p in _project_cache + ] + else: + _enum_items = [("", "Refresh projects...", "")] + return _enum_items + def project_items(self, context): - """Project dropdown. Cached because Blender calls this on every redraw.""" - if not _project_cache: - return [("", "Refresh projects…", "")] - return [(p["code"], "%s — %s" % (p["code"], p["name"]), "") for p in _project_cache] + """Called on every redraw, so it does no work and allocates nothing.""" + return _enum_items # ── Scene → job ─────────────────────────────────────────────────────────────── @@ -142,6 +158,7 @@ class VFXR_OT_refresh_projects(Operator): return {"CANCELLED"} _project_cache = data.get("projects", []) + rebuild_enum_items() self.report({"INFO"}, "%d project(s) loaded" % len(_project_cache)) return {"FINISHED"}