From: Mikko Rasa Date: Sun, 3 May 2020 22:22:55 +0000 (+0300) Subject: Update the Blender exporter for version 2.80 X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=commitdiff_plain;h=736a076cf12aca02492eae6c77eff846bde0cdda Update the Blender exporter for version 2.80 Textures are disabled for now. Blender's materials have changed significantly enough to be difficult to map to the current mspgl material system and I'm planning to do some changes to the library anyway. --- diff --git a/blender/io_mspgl/__init__.py b/blender/io_mspgl/__init__.py index 4c5fa8c2..bb13c488 100644 --- a/blender/io_mspgl/__init__.py +++ b/blender/io_mspgl/__init__.py @@ -1,5 +1,6 @@ bl_info = { "name": "Msp GL datafiles", + "blender": (2, 80, 0), "author": "Mikko Rasa", "location": "File > Export", "description": "Export Msp GL data", @@ -38,7 +39,7 @@ class ExportMspGLMeshBase(ExportMspGLBase): self.general_col = self.layout.column() col = self.layout.column() - col.label("Triangle strips") + col.label(text="Triangle strips") col.prop(self, "use_strips") col.prop(self, "use_degen_tris") @@ -75,7 +76,7 @@ class ExportMspGLObject(bpy.types.Operator, ExportMspGLMeshBase): self.general_col.prop(self, "use_textures") col = self.layout.column() - col.label("Files") + col.label(text="Files") col.prop(self, "single_file") if not self.single_file: col.prop(self, "shared_resources") @@ -132,7 +133,7 @@ class ExportMspGLScene(bpy.types.Operator, ExportMspGLBase): filename_ext = ".scene" selected_only = bpy.props.BoolProperty(name="Selected objects only", description="Only export the selected objects") - active_layers = bpy.props.BoolProperty(name="Active layers only", description="Only export objects on the active layers", default=True) + visible_collections = bpy.props.BoolProperty(name="Visible collections only", description="Only export objects in visible collections", default=True) resource_collection = bpy.props.BoolProperty(name="Resource collection", description="Put resources to a single collection file", default=True) skip_existing = bpy.props.BoolProperty(name="Skip existing files", description="Skip resources that already exist as files", default=True) @@ -143,7 +144,7 @@ class ExportMspGLScene(bpy.types.Operator, ExportMspGLBase): def draw(self, context): col = self.layout.column() col.prop(self, "selected_only") - col.prop(self, "active_layers") + col.prop(self, "visible_collections") col.prop(self, "resource_collection") if self.resource_collection: col.prop(self, "skip_existing") @@ -166,20 +167,22 @@ def menu_func_export(self, context): self.layout.operator(ExportMspGLScene.bl_idname, text="Msp GL scene") self.layout.operator(ExportMspGLCamera.bl_idname, text="Msp GL camera") -from .properties import MspGLMeshProperties, MspGLObjectProperties +classes = [ExportMspGLMesh, ExportMspGLObject, ExportMspGLArmature, ExportMspGLAnimation, ExportMspGLScene, ExportMspGLCamera] def register(): - bpy.utils.register_module(__name__) + for c in classes: + bpy.utils.register_class(c) - bpy.types.INFO_MT_file_export.append(menu_func_export) + bpy.types.TOPBAR_MT_file_export.append(menu_func_export) from .properties import register_properties register_properties() def unregister(): - bpy.utils.unregister_module(__name__) + for c in classes: + bpy.utils.unregister_class(c) - bpy.types.INFO_MT_file_export.remove(menu_func_export) + bpy.types.TOPBAR_MT_file_export.remove(menu_func_export) -if __name__=="__main__": - register() + from .properties import unregister_properties + unregister_properties() diff --git a/blender/io_mspgl/export_material.py b/blender/io_mspgl/export_material.py index 336ca316..356186df 100644 --- a/blender/io_mspgl/export_material.py +++ b/blender/io_mspgl/export_material.py @@ -18,7 +18,7 @@ class MaterialExporter: if mat_name not in resources: resources[mat_name] = self.export_material(material) - if self.use_textures: + if False and self.use_textures: for s in material.texture_slots: if s and s.texture.type=='IMAGE' and s.texture.image: tex_name = s.texture.name+".tex2d" @@ -31,7 +31,7 @@ class MaterialExporter: mat_res = resources[material.name+".mat"] textures = {} - if self.use_textures: + if False and self.use_textures: image_texture_slots = [s for s in material.texture_slots if s and s.texture.type=='IMAGE' and s.texture.image] for s in image_texture_slots: if s.use_map_color_diffuse: @@ -91,18 +91,17 @@ class MaterialExporter: from .util import get_colormap cm = get_colormap(material.srgb_colors) - if any(s.use_map_color_diffuse for s in material.texture_slots if s): + if False and any(s.use_map_color_diffuse for s in material.texture_slots if s): statements.append(Statement("diffuse", 1.0, 1.0, 1.0, 1.0)) amb = cm(material.ambient) statements.append(Statement("ambient", amb, amb, amb, 1.0)) else: - diff = material.diffuse_color*material.diffuse_intensity - statements.append(Statement("diffuse", cm(diff.r), cm(diff.g), cm(diff.b), 1.0)) - amb = diff*material.ambient - statements.append(Statement("ambient", cm(amb.r), cm(amb.g), cm(amb.b), 1.0)) + diff = material.diffuse_color + statements.append(Statement("diffuse", cm(diff[0]), cm(diff[1]), cm(diff[2]), 1.0)) + statements.append(Statement("ambient", cm(diff[0]), cm(diff[1]), cm(diff[2]), 1.0)) spec = material.specular_color*material.specular_intensity statements.append(Statement("specular", cm(spec.r), cm(spec.g), cm(spec.g), 1.0)) - statements.append(Statement("shininess", material.specular_hardness)) + statements.append(Statement("shininess", min(2/material.roughness**2-2, 250))) return mat_res diff --git a/blender/io_mspgl/export_scene.py b/blender/io_mspgl/export_scene.py index ac812abf..cb623a15 100644 --- a/blender/io_mspgl/export_scene.py +++ b/blender/io_mspgl/export_scene.py @@ -4,7 +4,7 @@ import os class SceneExporter: def __init__(self): self.selected_only = False - self.active_layers = True + self.visible_collections = True self.resource_collection = True self.skip_existing = True self.show_progress = True @@ -14,9 +14,9 @@ class SceneExporter: objs = context.selected_objects else: objs = context.scene.objects - if self.active_layers: - layers = context.scene.layers - objs = [o for o in objs if any(a and b for a, b in zip(layers, o.layers))] + if self.visible_collections: + collections = [c.collection for c in context.view_layer.layer_collection.children if not (c.hide_viewport or c.collection.hide_viewport)] + objs = [o for o in objs if any((o.name in c.all_objects) for c in collections)] objs = [o for o in objs if o.type=="MESH" and not o.lod_for_parent] objs = [o for o in objs if (not o.compound or o.parent not in objs)] objs.sort(key=lambda x:x.name) diff --git a/blender/io_mspgl/material.py b/blender/io_mspgl/material.py index a45e8815..470ffc57 100644 --- a/blender/io_mspgl/material.py +++ b/blender/io_mspgl/material.py @@ -8,6 +8,7 @@ class MaterialMap: else: self.name = "material_map" self.materials = materials + self.material_names = [m.name for m in self.materials] self.srgb_colors = materials[0].srgb_colors for m in self.materials: if m.technique!=self.technique: @@ -29,12 +30,12 @@ class MaterialMap: cm = get_colormap(self.srgb_colors) self.diffuse_data = "" for m in self.materials: - diff = [int(cm(c)*255) for c in m.diffuse_color*m.diffuse_intensity] - self.diffuse_data += "\\x{:02X}\\x{:02X}\\x{:02X}\\x{:02X}".format(*diff, int(m.ambient*255)) + diff = [int(cm(c)*255) for c in m.diffuse_color] + self.diffuse_data += "\\x{:02X}\\x{:02X}\\x{:02X}\\xFF".format(*diff) self.diffuse_data += "\\x00\\x00\\x00\\x00"*(self.size[0]*self.size[1]-count) def get_material_uv(self, material): - index = self.materials.index(material) + index = self.material_names.index(material.name) x = index%self.size[0] y = index//self.size[0] return ((x+0.5)/self.size[0], (y+0.5)/self.size[1]) diff --git a/blender/io_mspgl/mesh.py b/blender/io_mspgl/mesh.py index 91648d28..4403c6a0 100644 --- a/blender/io_mspgl/mesh.py +++ b/blender/io_mspgl/mesh.py @@ -239,7 +239,7 @@ class Mesh: def transform(self, matrix): for v in self.vertices: - v.co = matrix*v.co + v.co = matrix@v.co def splice(self, other): if len(self.uv_layers)!=len(other.uv_layers): @@ -275,8 +275,7 @@ class Mesh: self.faces += other.faces for f in self.faces[offset:]: f.index += offset - f.loop_start += loop_offset - f.loop_indices = range(f.loop_start, f.loop_start+f.loop_total) + f.loop_indices = range(f.loop_indices.start+offset, f.loop_indices.stop+offset) if other.materials: f.material_index = material_map[f.material_index] @@ -395,7 +394,7 @@ class Mesh: def apply_material_map(self, material_map): for m in self.materials: - if m not in material_map.materials: + if m.name not in material_map.material_names: raise Exception("Material map is not compatible with Mesh") if self.use_uv=='NONE': @@ -420,7 +419,7 @@ class Mesh: def prepare_uv(self, progress): # Form a list of UV layers referenced by materials with the array atlas # property set - array_uv_layers = [t.uv_layer for m in self.materials if m.array_atlas for t in m.texture_slots if t and t.texture_coords=='UV'] + array_uv_layers = [] #[t.uv_layer for m in self.materials if m.array_atlas for t in m.texture_slots if t and t.texture_coords=='UV'] array_uv_layers = [u for u in self.uv_layers if u.name in array_uv_layers] if array_uv_layers: @@ -779,11 +778,12 @@ def create_mesh_from_object(context, obj, progress, *, material_map=None): if c.type=="MESH" and c.compound: objs.append((c, m*c.matrix_local)) + dg = context.evaluated_depsgraph_get() + mesh = None - bmeshes = [] for o, m in objs: - bmesh = o.to_mesh(context.scene, True, "PREVIEW") - bmeshes.append(bmesh) + eval_obj = o.evaluated_get(dg) + bmesh = eval_obj.to_mesh() # Object.to_mesh does not copy custom properties bmesh.winding_test = o.data.winding_test @@ -798,6 +798,10 @@ def create_mesh_from_object(context, obj, progress, *, material_map=None): me = Mesh(bmesh) me.transform(m) + for i, s in enumerate(eval_obj.material_slots): + if s.link=='OBJECT': + me.materials[i] = s.material + if mesh: mesh.splice(me) else: @@ -822,8 +826,6 @@ def create_mesh_from_object(context, obj, progress, *, material_map=None): # Discard the temporary Blender meshes after making sure there's no # references to the data mesh.drop_references() - for m in bmeshes: - bpy.data.meshes.remove(m) progress.pop_task() diff --git a/blender/io_mspgl/properties.py b/blender/io_mspgl/properties.py index 032bf8ed..ce4e692f 100644 --- a/blender/io_mspgl/properties.py +++ b/blender/io_mspgl/properties.py @@ -20,7 +20,7 @@ class MspGLMeshProperties(bpy.types.Panel): self.layout.separator() col = self.layout.column() - col.label("Data selection") + col.label(text="Data selection") col.prop(mesh, "use_lines") col.prop(mesh, "vertex_groups") col.prop(mesh, "max_groups_per_vertex") @@ -28,7 +28,7 @@ class MspGLMeshProperties(bpy.types.Panel): self.layout.separator() col = self.layout.column() - col.label("Texturing") + col.label(text="Texturing") col.prop(mesh, "use_uv") col.prop(mesh, "tbn_vecs") col.prop(mesh, "tbn_uvtex") @@ -93,6 +93,8 @@ class MspGLTextureProperties(bpy.types.Panel): self.layout.prop(tex, "default_filter") +classes = [MspGLMeshProperties, MspGLObjectProperties, MspGLMaterialProperties, MspGLTextureProperties] + def register_properties(): bpy.types.Mesh.winding_test = bpy.props.BoolProperty(name="Winding test", description="Perform winding test to skip back faces") bpy.types.Mesh.smoothing = bpy.props.EnumProperty(name="Smoothing", description="Smoothing method to use", default="MSPGL", @@ -122,3 +124,10 @@ def register_properties(): bpy.types.Material.material_map = bpy.props.BoolProperty(name="Material map", description="Make this material part of a material map") bpy.types.Texture.default_filter = bpy.props.BoolProperty(name="Default filter", description="Let the loading program determine filtering options") + + for c in classes: + bpy.utils.register_class(c) + +def unregister_properties(): + for c in classes: + bpy.utils.unregister_class(c)