PsychoBlend: fixed some bugs and made exporting even faster.
This commit is contained in:
parent
9025715335
commit
7236d2e666
|
@ -1,6 +1,6 @@
|
|||
import bpy
|
||||
|
||||
from .util import escape_name, mat2str, needs_def_mb, needs_xform_mb
|
||||
from .util import escape_name, mat2str, needs_def_mb, needs_xform_mb, ExportCancelled
|
||||
|
||||
class Assembly:
|
||||
def __init__(self, render_engine, objects, visible_layers, group_prefix="", translation_offset=(0,0,0)):
|
||||
|
@ -80,10 +80,21 @@ class Assembly:
|
|||
|
||||
def take_sample(self, render_engine, scene, time):
|
||||
for mat in self.materials:
|
||||
# Check if render is cancelled
|
||||
if render_engine.test_break():
|
||||
raise ExportCancelled()
|
||||
mat.take_sample(render_engine, scene, time)
|
||||
|
||||
for ob in self.objects:
|
||||
# Check if render is cancelled
|
||||
if render_engine.test_break():
|
||||
raise ExportCancelled()
|
||||
ob.take_sample(render_engine, scene, time)
|
||||
|
||||
for inst in self.instances:
|
||||
# Check if render is cancelled
|
||||
if render_engine.test_break():
|
||||
raise ExportCancelled()
|
||||
inst.take_sample(render_engine, time, self.translation_offset)
|
||||
|
||||
def cleanup(self):
|
||||
|
@ -131,11 +142,13 @@ class Mesh:
|
|||
def __init__(self, render_engine, ob, name):
|
||||
self.ob = ob
|
||||
self.name = name
|
||||
self.needs_mb = needs_def_mb(self.ob)
|
||||
self.time_meshes = []
|
||||
|
||||
def take_sample(self, render_engine, scene, time):
|
||||
render_engine.update_stats("", "Psychopath: Collecting '%s' at time %f" % (self.ob.name, time))
|
||||
self.time_meshes += [self.ob.to_mesh(scene, True, 'RENDER')]
|
||||
if len(self.time_meshes) == 0 or self.needs_mb:
|
||||
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.ob.name, time))
|
||||
self.time_meshes += [self.ob.to_mesh(scene, True, 'RENDER')]
|
||||
|
||||
def cleanup(self):
|
||||
for mesh in self.time_meshes:
|
||||
|
@ -184,7 +197,7 @@ class SphereLamp:
|
|||
self.time_rad = []
|
||||
|
||||
def take_sample(self, render_engine, scene, time):
|
||||
render_engine.update_stats("", "Psychopath: Collecting '%s' at time %f" % (self.ob.name, time))
|
||||
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.ob.name, time))
|
||||
self.time_col += [self.ob.data.color * self.ob.data.energy]
|
||||
self.time_rad += [self.ob.data.shadow_soft_size]
|
||||
|
||||
|
@ -215,7 +228,7 @@ class RectLamp:
|
|||
self.time_dim = []
|
||||
|
||||
def take_sample(self, render_engine, scene, time):
|
||||
render_engine.update_stats("", "Psychopath: Collecting '%s' at time %f" % (self.ob.name, time))
|
||||
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.ob.name, time))
|
||||
self.time_col += [self.ob.data.color * self.ob.data.energy]
|
||||
if ob.data.shape == 'RECTANGLE':
|
||||
self.time_dim += [(self.ob.data.size, self.ob.data.size_y)]
|
||||
|
@ -243,15 +256,17 @@ class Instance:
|
|||
def __init__(self, render_engine, ob, data_name):
|
||||
self.ob = ob
|
||||
self.data_name = data_name
|
||||
self.needs_mb = needs_xform_mb(self.ob)
|
||||
self.time_xforms = []
|
||||
|
||||
def take_sample(self, render_engine, time, translation_offset):
|
||||
render_engine.update_stats("", "Psychopath: Collecting '%s' at time %f" % (self.ob.name, time))
|
||||
mat = self.ob.matrix_world.copy()
|
||||
mat[0][3] += translation_offset[0]
|
||||
mat[1][3] += translation_offset[1]
|
||||
mat[2][3] += translation_offset[2]
|
||||
self.time_xforms += [mat]
|
||||
if len(self.time_xforms) == 0 or self.needs_mb:
|
||||
render_engine.update_stats("", "Psychopath: Collecting '{}' xforms at time {}".format(self.ob.name, time))
|
||||
mat = self.ob.matrix_world.copy()
|
||||
mat[0][3] += translation_offset[0]
|
||||
mat[1][3] += translation_offset[1]
|
||||
mat[2][3] += translation_offset[2]
|
||||
self.time_xforms += [mat]
|
||||
|
||||
def export(self, render_engine, w):
|
||||
render_engine.update_stats("", "Psychopath: Exporting %s" % self.ob.name)
|
||||
|
|
|
@ -4,13 +4,7 @@ from math import degrees, pi, log
|
|||
from mathutils import Vector, Matrix
|
||||
|
||||
from .assembly import Assembly
|
||||
from .util import escape_name, mat2str
|
||||
|
||||
class ExportCancelled(Exception):
|
||||
""" Indicates that the render was cancelled in the middle of exporting
|
||||
the scene file.
|
||||
"""
|
||||
pass
|
||||
from .util import escape_name, mat2str, ExportCancelled
|
||||
|
||||
|
||||
class IndentedWriter:
|
||||
|
@ -181,7 +175,7 @@ class PsychoExporter:
|
|||
root_assembly.export(self.render_engine, self.w)
|
||||
except ExportCancelled:
|
||||
root_assembly.cleanup()
|
||||
raise ExportCancelled()
|
||||
raise
|
||||
else:
|
||||
root_assembly.cleanup()
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class PsychopathRender(bpy.types.RenderEngine):
|
|||
return psy_binary
|
||||
return ""
|
||||
|
||||
def _render(self, scene, psy_filepath, use_stdin, crop):
|
||||
def _start_psychopath(self, scene, psy_filepath, use_stdin, crop):
|
||||
psy_binary = PsychopathRender._locate_binary()
|
||||
if not psy_binary:
|
||||
print("Psychopath: could not execute psychopath, possibly Psychopath isn't installed")
|
||||
|
@ -86,6 +86,15 @@ class PsychopathRender(bpy.types.RenderEngine):
|
|||
self.end_result(result)
|
||||
|
||||
def render(self, scene):
|
||||
self._process = None
|
||||
try:
|
||||
self._render(scene)
|
||||
except:
|
||||
if self.process != None:
|
||||
self._process.terminate()
|
||||
raise
|
||||
|
||||
def _render(self, scene):
|
||||
# has to be called to update the frame on exporting animations
|
||||
scene.frame_set(scene.frame_current)
|
||||
|
||||
|
@ -116,22 +125,19 @@ class PsychopathRender(bpy.types.RenderEngine):
|
|||
|
||||
if use_stdin:
|
||||
# Start rendering
|
||||
if not self._render(scene, export_path, use_stdin, crop):
|
||||
if not self._start_psychopath(scene, export_path, use_stdin, crop):
|
||||
self.update_stats("", "Psychopath: Not found")
|
||||
return
|
||||
|
||||
self.update_stats("", "Psychopath: Collecting...")
|
||||
# Export to Psychopath's stdin
|
||||
try:
|
||||
if not psy_export.PsychoExporter(self._process.stdin, self, scene).export_psy():
|
||||
# Render cancelled in the middle of exporting,
|
||||
# so just return.
|
||||
return
|
||||
self._process.stdin.write(bytes("__PSY_EOF__", "utf-8"))
|
||||
self._process.stdin.flush()
|
||||
except:
|
||||
if not psy_export.PsychoExporter(self._process.stdin, self, scene).export_psy():
|
||||
# Render cancelled in the middle of exporting,
|
||||
# so just return.
|
||||
self._process.terminate()
|
||||
raise
|
||||
return
|
||||
self._process.stdin.write(bytes("__PSY_EOF__", "utf-8"))
|
||||
self._process.stdin.flush()
|
||||
|
||||
self.update_stats("", "Psychopath: Building")
|
||||
else:
|
||||
|
@ -145,7 +151,7 @@ class PsychopathRender(bpy.types.RenderEngine):
|
|||
|
||||
# Start rendering
|
||||
self.update_stats("", "Psychopath: Rendering from %s" % export_path)
|
||||
if not self._render(scene, export_path, use_stdin, crop):
|
||||
if not self._start_psychopath(scene, export_path, use_stdin, crop):
|
||||
self.update_stats("", "Psychopath: Not found")
|
||||
return
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
class ExportCancelled(Exception):
|
||||
""" Indicates that the render was cancelled in the middle of exporting
|
||||
the scene file.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def mat2str(m):
|
||||
""" Converts a matrix into a single-line string of values.
|
||||
"""
|
||||
|
@ -12,14 +19,33 @@ def needs_def_mb(ob):
|
|||
""" Determines if the given object needs to be exported with
|
||||
deformation motion blur or not.
|
||||
"""
|
||||
anim = ob.animation_data
|
||||
no_anim_data = anim == None or (anim.action == None and len(anim.nla_tracks) == 0 and len(anim.drivers) == 0)
|
||||
|
||||
for mod in ob.modifiers:
|
||||
if mod.type == 'SUBSURF':
|
||||
pass
|
||||
elif mod.type == 'MULTIRES':
|
||||
pass
|
||||
elif mod.type == 'MIRROR':
|
||||
if mod.mirror_object == None:
|
||||
pass
|
||||
else:
|
||||
return True
|
||||
elif mod.type == 'BEVEL' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'EDGE_SPLIT' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'SOLIDIFY' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'MASK' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'REMESH' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'TRIANGULATE' and no_anim_data:
|
||||
pass
|
||||
elif mod.type == 'WIREFRAME' and no_anim_data:
|
||||
pass
|
||||
else:
|
||||
return True
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user