From d22b7170b7bb7fab33e958f8219e9da3b52975c1 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 4 Aug 2021 14:46:13 -0400 Subject: [PATCH] Fix mesh manager chicken/egg problem. --- korman/exporter/convert.py | 2 +- korman/exporter/etlight.py | 25 +++++++++++++++++++------ korman/exporter/mesh.py | 5 +++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/korman/exporter/convert.py b/korman/exporter/convert.py index bded50d..811e313 100644 --- a/korman/exporter/convert.py +++ b/korman/exporter/convert.py @@ -58,7 +58,7 @@ class Exporter: self.image = image.ImageCache(self) self.locman = locman.LocalizationConverter(self) self.decal = decal.DecalConverter(self) - self.oven = etlight.LightBaker(self.report) + self.oven = etlight.LightBaker(mesh=self.mesh, report=self.report) # Step 0.8: Init the progress mgr self.mesh.add_progress_presteps(self.report) diff --git a/korman/exporter/etlight.py b/korman/exporter/etlight.py index 588a6b6..70bbb0f 100644 --- a/korman/exporter/etlight.py +++ b/korman/exporter/etlight.py @@ -25,10 +25,10 @@ from ..helpers import * _NUM_RENDER_LAYERS = 20 -class LightBaker(_MeshManager): +class LightBaker: """ExportTime Lighting""" - def __init__(self, report=None, *, verbose=False): + def __init__(self, *, mesh=None, report=None, verbose=False): self._lightgroups = {} if report is None: self._report = ExportVerboseLogger() if verbose else ExportProgressLogger() @@ -38,7 +38,11 @@ class LightBaker(_MeshManager): else: self._report = report self._own_report = False - super().__init__(self._report) + + # This used to be the base class, but due to the need to access the export state + # which may be stored in the exporter's mesh manager, we've changed from is-a to has-a + # semantics. Sorry for this confusion! + self._mesh = _MeshManager(self._report) if mesh is None else mesh self.vcol_layer_name = "autocolor" self.lightmap_name = "{}_LIGHTMAPGEN.png" @@ -52,6 +56,13 @@ class LightBaker(_MeshManager): if self._own_report: self._report.progress_end() + def __enter__(self): + self._mesh.__enter__() + return self + + def __exit__(self, *exc_info): + self._mesh.__exit__(*exc_info) + @staticmethod def add_progress_steps(report, add_base=False): if add_base: @@ -385,8 +396,10 @@ class LightBaker(_MeshManager): # Meshes with modifiers need to have islands packed to prevent generated vertices # from sharing UVs. Sigh. - if self.is_collapsed(bo): - self._report.warn("'{}': packing islands in UV Texture '{}' due to modifier collapse", bo.name, uv_base.name) + if self._mesh.is_collapsed(bo): + # Danger: uv_base.name -> UnicodeDecodeError (wtf? another blender bug?) + self._report.warn("'{}': packing islands in UV Texture '{}' due to modifier collapse", + bo.name, modifier.uv_map, indent=2) with self._set_mode("EDIT"): bpy.ops.mesh.select_all(action="SELECT") bpy.ops.uv.pack_islands(margin=0.01) @@ -441,7 +454,7 @@ class LightBaker(_MeshManager): # future exports as an optimization. We won't reach this point if there is already an # autocolor layer (gulp). if not self.force and needs_vcol_layer: - self.context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove)) + self._mesh.context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove)) # Indicate we should bake return True diff --git a/korman/exporter/mesh.py b/korman/exporter/mesh.py index caeea81..77acd21 100644 --- a/korman/exporter/mesh.py +++ b/korman/exporter/mesh.py @@ -167,6 +167,7 @@ class _MeshManager: self.context_stack = ExitStack() if report is not None: self._report = report + self._entered = False self._overrides = {} @staticmethod @@ -183,6 +184,9 @@ class _MeshManager: return props def __enter__(self): + assert self._entered is False, "_MeshManager is not reentrant" + self._entered = True + self.context_stack.__enter__() scene = bpy.context.scene @@ -231,6 +235,7 @@ class _MeshManager: if key in {"name", "type"} or (cached_mod["type"], key) in readonly_attributes: continue setattr(mod, key, value) + self._entered = False def is_collapsed(self, bo) -> bool: return bo.name in self._overrides