Browse Source

Fix #266.

This ensures that autocolor layers are disposed before their temporary
mesh objects are disposed.
pull/268/head
Adam Johnson 3 years ago
parent
commit
15bbcc3d89
Signed by: Hoikas
GPG Key ID: 0B6515D6FF6F271E
  1. 5
      korman/exporter/convert.py
  2. 7
      korman/exporter/etlight.py
  3. 41
      korman/exporter/mesh.py

5
korman/exporter/convert.py

@ -16,7 +16,6 @@
import bpy import bpy
from pathlib import Path from pathlib import Path
from contextlib import ExitStack
from ..korlib import ConsoleToggler from ..korlib import ConsoleToggler
@ -47,7 +46,7 @@ class Exporter:
def run(self): def run(self):
log = logger.ExportVerboseLogger if self._op.verbose else logger.ExportProgressLogger log = logger.ExportVerboseLogger if self._op.verbose else logger.ExportProgressLogger
with ConsoleToggler(self._op.show_console), log(self._op.filepath) as self.report, ExitStack() as self.context_stack: with ConsoleToggler(self._op.show_console), log(self._op.filepath) as self.report:
# Step 0: Init export resmgr and stuff # Step 0: Init export resmgr and stuff
self.mgr = manager.ExportManager(self) self.mgr = manager.ExportManager(self)
self.mesh = mesh.MeshConverter(self) self.mesh = mesh.MeshConverter(self)
@ -59,7 +58,7 @@ class Exporter:
self.image = image.ImageCache(self) self.image = image.ImageCache(self)
self.locman = locman.LocalizationConverter(self) self.locman = locman.LocalizationConverter(self)
self.decal = decal.DecalConverter(self) self.decal = decal.DecalConverter(self)
self.oven = etlight.LightBaker(self.report, stack=self.context_stack) self.oven = etlight.LightBaker(self.report)
# Step 0.8: Init the progress mgr # Step 0.8: Init the progress mgr
self.mesh.add_progress_presteps(self.report) self.mesh.add_progress_presteps(self.report)

7
korman/exporter/etlight.py

@ -28,7 +28,7 @@ _NUM_RENDER_LAYERS = 20
class LightBaker(_MeshManager): class LightBaker(_MeshManager):
"""ExportTime Lighting""" """ExportTime Lighting"""
def __init__(self, report=None, stack=None, *, verbose=False): def __init__(self, report=None, *, verbose=False):
self._lightgroups = {} self._lightgroups = {}
if report is None: if report is None:
self._report = ExportVerboseLogger() if verbose else ExportProgressLogger() self._report = ExportVerboseLogger() if verbose else ExportProgressLogger()
@ -40,7 +40,6 @@ class LightBaker(_MeshManager):
self._own_report = False self._own_report = False
super().__init__(self._report) super().__init__(self._report)
self._context_stack = stack
self.vcol_layer_name = "autocolor" self.vcol_layer_name = "autocolor"
self.lightmap_name = "{}_LIGHTMAPGEN.png" self.lightmap_name = "{}_LIGHTMAPGEN.png"
self.lightmap_uvtex_name = "LIGHTMAPGEN" self.lightmap_uvtex_name = "LIGHTMAPGEN"
@ -445,8 +444,8 @@ class LightBaker(_MeshManager):
# nukage. If we're in the lightmap operators, we clearly want this to persist for # nukage. If we're in the lightmap operators, we clearly want this to persist for
# future exports as an optimization. We won't reach this point if there is already an # future exports as an optimization. We won't reach this point if there is already an
# autocolor layer (gulp). # autocolor layer (gulp).
if self._context_stack is not None and needs_vcol_layer: if not self.force and needs_vcol_layer:
self._context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove)) self.context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove))
# Indicate we should bake # Indicate we should bake
return True return True

41
korman/exporter/mesh.py

@ -14,6 +14,7 @@
# along with Korman. If not, see <http://www.gnu.org/licenses/>. # along with Korman. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
from contextlib import ExitStack
import itertools import itertools
from PyHSPlasma import * from PyHSPlasma import *
from math import fabs from math import fabs
@ -163,6 +164,7 @@ class _GeoData:
class _MeshManager: class _MeshManager:
def __init__(self, report=None): def __init__(self, report=None):
self.context_stack = ExitStack()
if report is not None: if report is not None:
self._report = report self._report = report
self._overrides = {} self._overrides = {}
@ -181,6 +183,8 @@ class _MeshManager:
return props return props
def __enter__(self): def __enter__(self):
self.context_stack.__enter__()
scene = bpy.context.scene scene = bpy.context.scene
self._report.progress_advance() self._report.progress_advance()
self._report.progress_range = len(scene.objects) self._report.progress_range = len(scene.objects)
@ -207,23 +211,26 @@ class _MeshManager:
self._report.progress_increment() self._report.progress_increment()
return self return self
def __exit__(self, type, value, traceback): def __exit__(self, *exc_info):
data_bos, data_meshes = bpy.data.objects, bpy.data.meshes try:
for obj_name, override in self._overrides.items(): self.context_stack.__exit__(*exc_info)
bo = data_bos.get(obj_name) finally:
data_bos, data_meshes = bpy.data.objects, bpy.data.meshes
# Reapply the old mesh for obj_name, override in self._overrides.items():
trash_mesh, bo.data = bo.data, data_meshes.get(override["mesh"]) bo = data_bos.get(obj_name)
data_meshes.remove(trash_mesh)
# Reapply the old mesh
# If modifiers were removed, reapply them now unless they're read-only. trash_mesh, bo.data = bo.data, data_meshes.get(override["mesh"])
readonly_attributes = {("DECIMATE", "face_count"),} data_meshes.remove(trash_mesh)
for cached_mod in override["modifiers"]:
mod = bo.modifiers.new(cached_mod["name"], cached_mod["type"]) # If modifiers were removed, reapply them now unless they're read-only.
for key, value in cached_mod.items(): readonly_attributes = {("DECIMATE", "face_count"),}
if key in {"name", "type"} or (cached_mod["type"], key) in readonly_attributes: for cached_mod in override["modifiers"]:
continue mod = bo.modifiers.new(cached_mod["name"], cached_mod["type"])
setattr(mod, key, value) for key, value in cached_mod.items():
if key in {"name", "type"} or (cached_mod["type"], key) in readonly_attributes:
continue
setattr(mod, key, value)
class MeshConverter(_MeshManager): class MeshConverter(_MeshManager):

Loading…
Cancel
Save