]> git.tdb.fi Git - libs/gl.git/commitdiff
Update the Blender exporter for version 2.80
authorMikko Rasa <tdb@tdb.fi>
Sun, 3 May 2020 22:22:55 +0000 (01:22 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 3 May 2020 22:22:55 +0000 (01:22 +0300)
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.

blender/io_mspgl/__init__.py
blender/io_mspgl/export_material.py
blender/io_mspgl/export_scene.py
blender/io_mspgl/material.py
blender/io_mspgl/mesh.py
blender/io_mspgl/properties.py

index 4c5fa8c22ce735f4322396ed01e120ee0827e14e..bb13c48873f2cf28008b2886a7a4ba6b79ce95ea 100644 (file)
@@ -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()
index 336ca31698e9d7b401305198040ca6da92f1d195..356186df17c5b2341e525322cc69f3607ce4513f 100644 (file)
@@ -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
 
index ac812abf7b115766ab0c08af3848614a4ff99ab4..cb623a1587f8fc14a0b15fe41c4eb30d4b3d6a4b 100644 (file)
@@ -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)
index a45e881571aea4c0da4b5678f3662eb189863d13..470ffc5784e1d4fd0b28d006dfe720863a172257 100644 (file)
@@ -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])
index 91648d28e5b28b1ab6db369586b46d974b0c332e..4403c6a01dd92a2d1b2eff36cf95cd4e9853a120 100644 (file)
@@ -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()
 
index 032bf8ed5dbced582ecda1f4262da88080f94008..ce4e692f189883d9e137dfcc576bba268eb584d3 100644 (file)
@@ -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)