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
from pathlib import Path
from contextlib import ExitStack
from ..korlib import ConsoleToggler
@ -47,7 +46,7 @@ class Exporter:
def run(self):
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
self.mgr = manager.ExportManager(self)
self.mesh = mesh.MeshConverter(self)
@ -59,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, stack=self.context_stack)
self.oven = etlight.LightBaker(self.report)
# Step 0.8: Init the progress mgr
self.mesh.add_progress_presteps(self.report)

7
korman/exporter/etlight.py

@ -28,7 +28,7 @@ _NUM_RENDER_LAYERS = 20
class LightBaker(_MeshManager):
"""ExportTime Lighting"""
def __init__(self, report=None, stack=None, *, verbose=False):
def __init__(self, report=None, *, verbose=False):
self._lightgroups = {}
if report is None:
self._report = ExportVerboseLogger() if verbose else ExportProgressLogger()
@ -40,7 +40,6 @@ class LightBaker(_MeshManager):
self._own_report = False
super().__init__(self._report)
self._context_stack = stack
self.vcol_layer_name = "autocolor"
self.lightmap_name = "{}_LIGHTMAPGEN.png"
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
# future exports as an optimization. We won't reach this point if there is already an
# autocolor layer (gulp).
if self._context_stack is not None and needs_vcol_layer:
self._context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove))
if not self.force and needs_vcol_layer:
self.context_stack.enter_context(TemporaryObject(vcol_layer, vcols.remove))
# Indicate we should bake
return True

41
korman/exporter/mesh.py

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

Loading…
Cancel
Save