diff --git a/blender_addon/io_symmetry_exp/__init__.py b/blender_addon/io_symmetry_exp/__init__.py index aa3feb4..b68c64e 100755 --- a/blender_addon/io_symmetry_exp/__init__.py +++ b/blender_addon/io_symmetry_exp/__init__.py @@ -3,31 +3,120 @@ bl_info = { "description": "Export to a format that can be read by Symmetry", "author": "Shariq Shah", "version": (0, 1), - "blender": (2, 79, 0), + "blender": (2, 80, 0), "location": "File > Export > Export to Symmetry", "category": "Import-Export" } -# Ensure that we reload our dependencies if we ourselves are reloaded by Blender -if "bpy" in locals(): - import imp; - if "exporter" in locals(): - imp.reload(exporter); - import bpy -from . import exporter +import bmesh +import struct +from math import radians +from bpy_extras.io_utils import ExportHelper + +class ExportSymmetry(bpy.types.Operator, ExportHelper): + bl_idname = "export_symmetry.symbres"; + bl_label = "Symmetry Exporter"; + bl_options = {'PRESET'}; + filename_ext = ".symbres"; + + def execute(self, context): + scene = context.scene + view_layer = bpy.context.view_layer + activeObject = view_layer.objects.active + #activeObject = scene.objects.active + + if not activeObject or str(activeObject.type) != 'MESH': + raise NameError("Cannot export : Object %s is not a mesh" % activeObject) + + print("Exporting : " + activeObject.name) + + # Rotate -90 deg on x axis to compensate for blender's different orientation + activeObject.rotation_euler[0] = radians(-90) + bpy.ops.object.transform_apply(location = True, scale = True, rotation = True) + + mesh = activeObject.to_mesh(preserve_all_data_layers=True) + bm = bmesh.new() + bm.from_mesh(mesh) + bmesh.ops.triangulate(bm, faces = bm.faces) + + indices = [] + vertices = [] + normals = [] + uvs = [] + + if len(mesh.uv_layers) > 0: + uv_layer = bm.loops.layers.uv.values()[0] + index = 0; + for face in bm.faces: + for loop in face.loops: + uv = loop[uv_layer].uv + uv.y = 1.0 - uv.y + vert = loop.vert + vertices.append(vert.co.to_tuple()) + normals.append(vert.normal.to_tuple()) + uvs.append(uv.to_tuple()) + indices.append(index) + index += 1 + else: + raise NameError("No uv layers detected. Did you forget to unwrap?") + + bm.free() + del bm + + # Reset object's previous rotation + activeObject.rotation_euler[0] = radians(90) + bpy.ops.object.transform_apply(location = True, scale = True, rotation = True) + + file = open(self.filepath, 'bw') + + # Header + file.write(struct.pack('i', len(indices))) + file.write(struct.pack('i', len(vertices))) + file.write(struct.pack('i', len(normals))) + file.write(struct.pack('i', len(uvs))) + + print ("Num Indices : %d" % len(indices)) + print ("Indices : \n %s \n\n" % str(indices)) + + print ("Num Vertices : %d" % len(vertices)) + print ("Vertices : \n %s \n\n" % str(vertices)) + + print ("Num Normals : %d" % len(normals)) + print ("Normals : \n %s \n\n" % str(normals)) + + print ("Num UVs : %d" % len(uvs)) + print ("UVs : \n %s \n\n" % str(uvs)) + + # Body + for index in indices: + file.write(struct.pack('i', index)) + + for vertex in vertices: + file.write(struct.pack('fff', vertex[0], vertex[1], vertex[2])) + + for normal in normals: + file.write(struct.pack('fff', normal[0], normal[1], normal[2])) + + for uv in uvs: + file.write(struct.pack('ff', uv[0], uv[1])) + + file.close() + + print("Done!") + return {'FINISHED'}; def menu_func(self, context): self.layout.operator(ExportSymmetry.bl_idname, text="Symbres (.symbres)"); def register(): - bpy.utils.register_module(__name__); - bpy.types.INFO_MT_file_export.append(menu_func); + bpy.utils.register_class(ExportSymmetry); + bpy.types.TOPBAR_MT_file_export.append(menu_func); def unregister(): - bpy.utils.unregister_module(__name__); - bpy.types.INFO_MT_file_export.remove(menu_func); + bpy.utils.unregister_class(ExportSymmetry); + bpy.types.TOPBAR_MT_file_export.remove(menu_func); if __name__ == "__main__": diff --git a/todo.txt b/todo.txt index 34d4c73..26f306b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,7 +1,14 @@ Todo: + - Add editor undo for transformation operations + - Add simple player fps controls + - Add material export for blender exporter? + - Remove flickering from selection in editor + - Better, more accurate picking - Allow renaming scene objects in editor + - Check if we still need to rotate by 90 degrees when exporting from blender + - Command to reload entities only + - Command history in console - Bring back debug variable display in editor and allow showing colours, textures etc - - Implment/Test reading/writing scene that has a mixture of default entites and entity archetypes - Serialize player, camera properties to file - Implement behaviour that avoids writing normal entities that do not have children or parent to file to avoid inconsistencies when loading them - Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode @@ -15,7 +22,6 @@ Todo: - Entity browser window which lists all existing entity types from where new entities can be creating by dragging and dropping on to the current scene - - Better, more accurate picking - Editor related messages/notifications in the bottom status bar ? Disable entity picking when tool is in use or only allow picking when pressing ALT ? Maybe remove physics engine and ode all together if we're not using it or investigate the memory leaks that it causes if we're going to keep it? @@ -343,4 +349,5 @@ Done: * Save default entity archetype to be loaded when there is not other archetype or in case of an error as fallback * Ensure cameras are not initialized multiple times * Fixed cameras not resizing to current resolution when scene is loaded/reloaded - * Added parameter to entity_load command that renames the newly loaded object to whatever the second specified parameter is \ No newline at end of file + * Added parameter to entity_load command that renames the newly loaded object to whatever the second specified parameter is + * Implment/Test reading/writing scene that has a mixture of default entites and entity archetypes \ No newline at end of file