207 lines
8.3 KiB
Python
207 lines
8.3 KiB
Python
import bpy
|
|
|
|
from .util import escape_name, mat2str, needs_def_mb, needs_xform_mb, ExportCancelled
|
|
from mathutils import Vector, Matrix
|
|
|
|
def make_object_data_cache(render_engine, depsgraph, ob, name):
|
|
if ob.type == 'MESH':
|
|
return Mesh(render_engine, depsgraph, ob, name)
|
|
elif ob.type == 'LIGHT':
|
|
if ob.data.type == 'POINT':
|
|
return SphereLamp(render_engine, depsgraph, ob, name)
|
|
elif ob.data.type == 'AREA':
|
|
return RectLamp(render_engine, depsgraph, ob, name)
|
|
elif ob.data.type == 'AREA':
|
|
return RectLamp(render_engine, depsgraph, ob, name)
|
|
|
|
class Mesh:
|
|
""" Holds data for a mesh to be exported.
|
|
"""
|
|
def __init__(self, render_engine, depsgraph, ob, name):
|
|
self.name = name
|
|
self.material_name = None
|
|
if len(ob.material_slots) >= 1 and ob.material_slots[0].material != None:
|
|
self.material_name = ob.material_slots[0].material.name
|
|
self.is_subdiv = ob.data.psychopath.is_subdivision_surface
|
|
self.needs_mb = needs_def_mb(ob)
|
|
self.time_meshes = []
|
|
|
|
def take_sample(self, render_engine, depsgraph, ob, time):
|
|
if len(self.time_meshes) == 0 or self.needs_mb:
|
|
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.name, time))
|
|
self.time_meshes += [ob.to_mesh(depsgraph=depsgraph).copy()]
|
|
|
|
def cleanup(self):
|
|
for mesh in self.time_meshes:
|
|
bpy.data.meshes.remove(mesh)
|
|
|
|
def export(self, render_engine, w):
|
|
render_engine.update_stats("", "Psychopath: Exporting %s" % self.name)
|
|
|
|
if self.is_subdiv == False:
|
|
# Exporting normal mesh
|
|
w.write("MeshSurface $%s {\n" % escape_name(self.name))
|
|
w.indent()
|
|
else:
|
|
# Exporting subdivision surface cage
|
|
w.write("SubdivisionSurface $%s {\n" % escape_name(self.name))
|
|
w.indent()
|
|
|
|
# Material bindings.
|
|
if self.material_name != None:
|
|
w.write("SurfaceShaderBind [${}]\n".format(escape_name(self.material_name)))
|
|
|
|
# Write vertices and (if it's smooth shaded) normals
|
|
for ti in range(len(self.time_meshes)):
|
|
w.write("Vertices [")
|
|
w.write(" ".join([("%f" % i) for vert in self.time_meshes[ti].vertices for i in vert.co]), False)
|
|
w.write("]\n", False)
|
|
if self.time_meshes[0].polygons[0].use_smooth and self.is_subdiv == False:
|
|
w.write("Normals [")
|
|
w.write(" ".join([("%f" % i) for vert in self.time_meshes[ti].vertices for i in vert.normal]), False)
|
|
w.write("]\n", False)
|
|
|
|
# Write face vertex counts
|
|
w.write("FaceVertCounts [")
|
|
w.write(" ".join([("%d" % len(p.vertices)) for p in self.time_meshes[0].polygons]), False)
|
|
w.write("]\n", False)
|
|
|
|
# Write face vertex indices
|
|
w.write("FaceVertIndices [")
|
|
w.write(" ".join([("%d"%v) for p in self.time_meshes[0].polygons for v in p.vertices]), False)
|
|
w.write("]\n", False)
|
|
|
|
# MeshSurface/SubdivisionSurface section end
|
|
w.unindent()
|
|
w.write("}\n")
|
|
|
|
|
|
class SphereLamp:
|
|
""" Holds data for a sphere light to be exported.
|
|
"""
|
|
def __init__(self, render_engine, depsgraph, ob, name):
|
|
self.name = name
|
|
self.time_col = []
|
|
self.time_rad = []
|
|
|
|
def take_sample(self, render_engine, depsgraph, ob, time):
|
|
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(ob.name, time))
|
|
|
|
if ob.data.psychopath.color_type == 'Rec709':
|
|
self.time_col += [('Rec709', ob.data.color * ob.data.energy)]
|
|
elif ob.data.psychopath.color_type == 'Blackbody':
|
|
self.time_col += [('Blackbody', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
elif ob.data.psychopath.color_type == 'ColorTemperature':
|
|
self.time_col += [('ColorTemperature', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
|
|
self.time_rad += [ob.data.shadow_soft_size]
|
|
|
|
def cleanup(self):
|
|
pass
|
|
|
|
def export(self, render_engine, w):
|
|
render_engine.update_stats("", "Psychopath: Exporting %s" % self.name)
|
|
|
|
w.write("SphereLight $%s {\n" % escape_name(self.name))
|
|
w.indent()
|
|
for col in self.time_col:
|
|
if col[0] == 'Rec709':
|
|
w.write("Color [rec709, %f %f %f]\n" % (col[1][0], col[1][1], col[1][2]))
|
|
elif col[0] == 'Blackbody':
|
|
w.write("Color [blackbody, %f %f]\n" % (col[1], col[2]))
|
|
elif col[0] == 'ColorTemperature':
|
|
w.write("Color [color_temperature, %f %f]\n" % (col[1], col[2]))
|
|
for rad in self.time_rad:
|
|
w.write("Radius [%f]\n" % rad)
|
|
|
|
w.unindent()
|
|
w.write("}\n")
|
|
|
|
|
|
class RectLamp:
|
|
""" Holds data for a rectangular light to be exported.
|
|
"""
|
|
def __init__(self, render_engine, depsgraph, ob, name):
|
|
self.name = name
|
|
self.time_col = []
|
|
self.time_dim = []
|
|
|
|
def take_sample(self, render_engine, depsgraph, ob, time):
|
|
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.name, time))
|
|
|
|
if ob.data.psychopath.color_type == 'Rec709':
|
|
self.time_col += [('Rec709', ob.data.color * ob.data.energy / 2)]
|
|
elif ob.data.psychopath.color_type == 'Blackbody':
|
|
self.time_col += [('Blackbody', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
elif ob.data.psychopath.color_type == 'ColorTemperature':
|
|
self.time_col += [('ColorTemperature', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
|
|
if ob.data.shape == 'RECTANGLE':
|
|
self.time_dim += [(ob.data.size, ob.data.size_y)]
|
|
else:
|
|
self.time_dim += [(ob.data.size, ob.data.size)]
|
|
|
|
def cleanup(self):
|
|
pass
|
|
|
|
def export(self, render_engine, w):
|
|
render_engine.update_stats("", "Psychopath: Exporting %s" % self.name)
|
|
|
|
w.write("RectangleLight $%s {\n" % escape_name(self.name))
|
|
w.indent()
|
|
for col in self.time_col:
|
|
if col[0] == 'Rec709':
|
|
w.write("Color [rec709, %f %f %f]\n" % (col[1][0], col[1][1], col[1][2]))
|
|
elif col[0] == 'Blackbody':
|
|
w.write("Color [blackbody, %f %f]\n" % (col[1], col[2]))
|
|
elif col[0] == 'ColorTemperature':
|
|
w.write("Color [color_temperature, %f %f]\n" % (col[1], col[2]))
|
|
for dim in self.time_dim:
|
|
w.write("Dimensions [%f %f]\n" % dim)
|
|
|
|
w.unindent()
|
|
w.write("}\n")
|
|
|
|
|
|
class DistantDiskLamp:
|
|
def __init__(self, render_engine, depsgraph, ob, name):
|
|
self.name = name
|
|
self.time_col = []
|
|
self.time_dir = []
|
|
self.time_rad = []
|
|
|
|
def take_sample(self, render_engine, depsgraph, ob, time):
|
|
render_engine.update_stats("", "Psychopath: Collecting '{}' at time {}".format(self.name, time))
|
|
self.time_dir += [tuple(ob.matrix_world.to_3x3() @ Vector((0, 0, -1)))]
|
|
|
|
if ob.data.psychopath.color_type == 'Rec709':
|
|
self.time_col += [('Rec709', ob.data.color * ob.data.energy)]
|
|
elif ob.data.psychopath.color_type == 'Blackbody':
|
|
self.time_col += [('Blackbody', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
elif ob.data.psychopath.color_type == 'ColorTemperature':
|
|
self.time_col += [('ColorTemperature', ob.data.psychopath.color_blackbody_temp, ob.data.energy)]
|
|
|
|
self.time_rad += [ob.data.shadow_soft_size]
|
|
|
|
def cleanup(self):
|
|
pass
|
|
|
|
def export(self, render_engine, w):
|
|
render_engine.update_stats("", "Psychopath: Exporting %s" % escape_name(self.name))
|
|
w.write("DistantDiskLight $%s {\n" % self.name)
|
|
w.indent()
|
|
for direc in self.time_dir:
|
|
w.write("Direction [%f %f %f]\n" % (direc[0], direc[1], direc[2]))
|
|
for col in self.time_col:
|
|
if col[0] == 'Rec709':
|
|
w.write("Color [rec709, %f %f %f]\n" % (col[1][0], col[1][1], col[1][2]))
|
|
elif col[0] == 'Blackbody':
|
|
w.write("Color [blackbody, %f %f]\n" % (col[1], col[2]))
|
|
elif col[0] == 'ColorTemperature':
|
|
w.write("Color [color_temperature, %f %f]\n" % (col[1], col[2]))
|
|
for rad in self.time_rad:
|
|
w.write("Radius [%f]\n" % rad)
|
|
|
|
w.unindent()
|
|
w.write("}\n")
|