X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=blender%2Fio_mspgl%2Fexport_mesh.py;h=1652c1a494756eec3c772718b01897297046e444;hb=1d0b0fcb7ad573053a8730a90f7fb33061038db2;hp=0d2e66ab442206b9f2454baa0ffe2e37f7557cb3;hpb=b61c103559c83d6fe7309f2ca4489f09e701c4cf;p=libs%2Fgl.git diff --git a/blender/io_mspgl/export_mesh.py b/blender/io_mspgl/export_mesh.py index 0d2e66ab..1652c1a4 100644 --- a/blender/io_mspgl/export_mesh.py +++ b/blender/io_mspgl/export_mesh.py @@ -1,6 +1,6 @@ import itertools import bpy -from .outfile import OutFile +import mathutils class VertexCache: def __init__(self, size): @@ -35,24 +35,23 @@ class VertexCache: class MeshExporter: def __init__(self): + self.show_progress = True self.use_strips = True - self.use_degen_tris = True + self.use_degen_tris = False self.max_strip_len = 1024 - self.optimize_cache = False + self.optimize_cache = True self.cache_size = 64 - self.export_lines = True + self.export_lines = False self.export_uv = "UNIT0" self.tbn_vecs = False self.tbn_uvtex = "" self.compound = False - self.object = False self.material_tex = False - self.textures = "REF" self.smoothing = "MSPGL" self.export_groups = False self.max_groups = 2 - def stripify(self, mesh, progress = None): + def stripify(self, mesh, progress=None): for f in mesh.faces: f.flag = False @@ -194,35 +193,58 @@ class MeshExporter: return strips, loose - def export(self, context, fn): + def export(self, context, out_file, objs=None, progress=None): + if objs: + objs = [(o, mathutils.Matrix()) for i in objs] + if self.compound: - objs = context.selected_objects - else: - objs = [context.active_object] + if objs is None: + objs = [(o, mathutils.Matrix()) for o in context.selected_objects] + check = objs + while check: + children = [] + for o, m in check: + for c in o.children: + if c.compound: + children.append((c, m*c.matrix_local)) + objs += children + check = children + elif objs is None: + objs = [(context.active_object, mathutils.Matrix())] if not objs: raise Exception("Nothing to export") - for o in objs: + for o, m in objs: if o.type!="MESH": raise Exception("Can only export Mesh data") from .mesh import Mesh from .util import Progress - progress = Progress() - progress.set_task("Preparing", 0.0, 0.0) + if self.show_progress: + if not progress: + progress = Progress(context) + progress.set_task("Preparing", 0.0, 0.0) + else: + progress = None mesh = None bmeshes = [] - for o in objs: + winding_test = False + for o, m in objs: + if o.data.winding_test: + winding_test = True bmesh = o.to_mesh(context.scene, True, "PREVIEW") bmeshes.append(bmesh) + me = Mesh(bmesh) + me.transform(m) if not mesh: - mesh = Mesh(bmesh) + mesh = me else: - mesh.splice(Mesh(bmesh)) + mesh.splice(me) - progress.set_task("Smoothing", 0.05, 0.35) + if progress: + progress.set_task("Smoothing", 0.05, 0.35) if self.smoothing=="NONE": mesh.flatten_faces() mesh.split_smooth(progress) @@ -234,11 +256,12 @@ class MeshExporter: mesh.sort_vertex_groups(self.max_groups) # Create a mapping from vertex group indices to bone indices - group_index_map = dict((i, i) for i in range(len(objs[0].vertex_groups))) - if objs[0].parent and objs[0].parent.type=="ARMATURE": - armature = objs[0].parent.data + first_obj = objs[0][0] + group_index_map = dict((i, i) for i in range(len(first_obj.vertex_groups))) + if first_obj.parent and first_obj.parent.type=="ARMATURE": + armature = first_obj.parent.data bone_indices = dict((armature.bones[i].name, i) for i in range(len(armature.bones))) - for g in objs[0].vertex_groups: + for g in first_obj.vertex_groups: if g.name in bone_indices: group_index_map[g.index] = bone_indices[g.name] @@ -246,13 +269,20 @@ class MeshExporter: mesh.generate_material_uv() texunits = [] - if mesh.uv_layers and self.export_uv!="NONE": + force_unit0 = False + if mesh.uv_layers and (self.export_uv!="NONE" or self.material_tex): # Figure out which UV layers to export - if self.export_uv=="UNIT0": - if mesh.uv_layers[0].unit==0: - texunits = [0] - else: + if self.export_uv=="ALL": texunits = range(len(mesh.uv_layers)) + elif self.material_tex: + # The material UV layer is always the last one + texunits = [len(mesh.uv_layers)-1] + force_unit0 = True + else: + for i, u in enumerate(mesh.uv_layers): + if u.unit==0: + texunits = [i] + break texunits = [(i, mesh.uv_layers[i]) for i in texunits] texunits = [u for u in texunits if not u[1].hidden] @@ -266,7 +296,8 @@ class MeshExporter: texunits.insert(0, unit) for i, u in texunits: - progress.set_task("Splitting UVs", 0.35+0.3*i/len(texunits), 0.35+0.3*(i+1)/len(texunits)) + if progress: + progress.set_task("Splitting UVs", 0.35+0.3*i/len(texunits), 0.35+0.3*(i+1)/len(texunits)) mesh.split_uv(i, progress) if self.tbn_vecs and u.name==self.tbn_uvtex: mesh.compute_uv() @@ -277,30 +308,32 @@ class MeshExporter: strips = [] loose = mesh.faces if self.use_strips: - progress.set_task("Creating strips", 0.65, 0.95) + if progress: + progress.set_task("Creating strips", 0.65, 0.95) strips, loose = self.stripify(mesh, progress) - progress.set_task("Writing file", 0.95, 1.0) + if progress: + progress.set_task("Writing file", 0.95, 1.0) - out_file = OutFile(fn) - if self.object: - out_file.begin("mesh") + from .outfile import open_output + out_file = open_output(out_file) - fmt = "NORMAL3" + fmt = ["NORMAL3"] if texunits: for i, u in texunits: - if u.unit==0: - fmt += "_TEXCOORD2" + size = str(len(mesh.vertices[0].uvs[i])) + if u.unit==0 or force_unit0: + fmt.append("TEXCOORD"+size) else: - fmt += "_TEXCOORD2%d"%u.unit + fmt.append("TEXCOORD%s_%d"%(size, u.unit)) if self.tbn_vecs: - fmt += "_ATTRIB33_ATTRIB34" + fmt += ["TANGENT3", "BINORMAL3"] if self.export_groups: - fmt += "_ATTRIB%d5"%(self.max_groups*2) - fmt += "_VERTEX3" - out_file.begin("vertices", fmt) + fmt.append("ATTRIB%d_5"%(self.max_groups*2)) + fmt.append("VERTEX3") + out_file.begin("vertices", *fmt) normal = None - uvs = [None]*len(texunits) + uvs = {} tan = None bino = None group = None @@ -309,18 +342,19 @@ class MeshExporter: out_file.write("normal3", *v.normal) normal = v.normal for i, u in texunits: - if v.uvs[i]!=uvs[i]: - if u.unit==0: - out_file.write("texcoord2", *v.uvs[i]) + if v.uvs[i]!=uvs.get(i): + size = str(len(v.uvs[i])) + if u.unit==0 or force_unit0: + out_file.write("texcoord"+size, *v.uvs[i]) else: - out_file.write("multitexcoord2", u.unit, *v.uvs[i]) + out_file.write("multitexcoord"+size, u.unit, *v.uvs[i]) uvs[i] = v.uvs[i] if self.tbn_vecs: if v.tan!=tan: - out_file.write("attrib3", 3, *v.tan) + out_file.write("tangent3", *v.tan) tan = v.tan if v.bino!=bino: - out_file.write("attrib3", 4, *v.bino) + out_file.write("binormal3", *v.bino) bino = v.bino if self.export_groups: group_attr = [(group_index_map[g.group], g.weight*v.group_weight_scale) for g in v.groups[:self.max_groups]] @@ -353,84 +387,18 @@ class MeshExporter: out_file.end() if self.export_lines and mesh.lines: - out_file.write("batch", "LINES") + out_file.begin("batch", "LINES") for l in mesh.lines: out_file.write("indices", l.vertices[0].index, l.vertices[1].index) out_file.end() - if self.object: - out_file.end() - out_file.begin("technique") - out_file.begin("pass", '""') - if mesh.materials: - if self.material_tex: - out_file.begin("material") - out_file.write("diffuse", 1.0, 1.0, 1.0, 1.0) - out_file.end() - index = 0 - for u in mesh.uv_layers: - if u.name=="material_tex": - index = u.unit - out_file.begin("texunit", index) - out_file.begin("texture2d") - out_file.write("min_filter", "NEAREST") - out_file.write("mag_filter", "NEAREST") - out_file.write("storage", "RGB", len(mesh.materials), 1) - texdata = '"' - for m in mesh.materials: - color = [int(c*255) for c in m.diffuse_color] - texdata += "\\x%02X\\x%02X\\x%02X"%tuple(color) - texdata += '"' - out_file.write("raw_data", texdata) - out_file.end() - out_file.end() - else: - mat = mesh.materials[0] - out_file.begin("material") - diff = mat.diffuse_color - out_file.write("diffuse", diff.r, diff.g, diff.b, 1.0) - amb = diff*mat.ambient - out_file.write("ambient", amb.r, amb.g, amb.b, 1.0) - spec = mat.specular_color*mat.specular_intensity - out_file.write("specular", spec.r, spec.g, spec.b, 1.0) - out_file.write("shininess", mat.specular_hardness); - out_file.end() - - if self.textures!="NONE": - for slot in mesh.materials[0].texture_slots: - if not slot: - continue - - tex = slot.texture - if tex.type!="IMAGE": - continue - - if slot.uv_layer: - for u in mesh.uv_layers: - if u.name==slot.uv_layer: - index = u.unit - else: - index = mesh.uv_layers[0].unit - - out_file.begin("texunit", index) - if self.textures=="INLINE": - out_file.begin("texture2d") - out_file.write("min_filter", "LINEAR") - out_file.write("storage", "RGBA", tex.image.size[0], tex.image.size[1]) - texdata = '"' - for p in tex.image.pixels: - texdata += "\\x%02X"%int(p*255) - texdata += '"' - out_file.write("raw_data", texdata) - out_file.end() - else: - out_file.write("texture", '"%s"'%tex.image.name) - out_file.end() + if winding_test: + out_file.write("winding", "COUNTERCLOCKWISE") - out_file.end() - out_file.end() - - progress.set_task("Done", 1.0, 1.0) + if progress: + progress.set_task("Done", 1.0, 1.0) for m in bmeshes: bpy.data.meshes.remove(m) + + return mesh