import os, bpy, struct from bpy_extras.io_utils import ExportHelper from bpy.props import StringProperty, BoolProperty, EnumProperty # This is a custom Blender export script to output an object to a format that's easy to use in # android. While open gl allows the use of an index buffer for vertices, the same cannot be done # for texture coordinates, which is why this script duplicates the vertices and normals. This # gives a larger but faster loading file, hence the tongue-in-cheek name "Compressed" object file. # The format is number of vertices + list of vertices (3 coord, 3 normal, 2 texcoord) bl_info = { "name": "COB Exporter", "description": "Exports the active scene into a Compressed Object file.", "author": "Stuart Scott", "version": (1, 0, 0), "blender": (2, 6, 2), "api": 36339, "location": "File > Export > COB Exporter (.cob)", "warning": "", # used for warning icon and text in addons panel "wiki_url": "", "tracker_url": "", "category": "Import-Export" } class COBExporter(bpy.types.Operator, ExportHelper): '''Exports the current scene into a Compressed Object format.''' bl_idname = "export.cob_exporter" # this is important since its how bpy.ops.export.cob_exporter is constructed bl_label = "COB Exporter" filename_ext = ".cob" filter_glob = StringProperty(default="*.cob", options={'HIDDEN'}) def execute(self, context): mesh = context.active_object if mesh.type != 'MESH': print("Active object is not a mesh") return {'FINISHED'} if mesh.mode != 'OBJECT': bpy.ops.object.mode_set(mode='OBJECT', toggle=False) print("Writing "+mesh.name+" to "+self.filepath) uvtex = mesh.data.uv_textures.active # points to active texture f = open(self.filepath, 'wb') f.write(struct.pack(">i", len(uvtex.data) * 3))# write length for uv_index, uv_itself in enumerate(uvtex.data): # get uv for this face uvs = uv_itself.uv1, uv_itself.uv2, uv_itself.uv3 for vertex_index, vertex_itself in enumerate(mesh.data.faces[uv_index].vertices): # for each vertex in the face vertex = mesh.data.vertices[vertex_itself] v = vertex.co.xyz n = vertex.normal.xyz t = uvs[vertex_index] f.write(struct.pack(">ffffffff", v[0], v[1], v[2], n[0], n[1], n[2], t[0], 1 - t[1])) f.close() return {'FINISHED'} @classmethod def poll(cls, context): return context.active_object != None # Only needed if you want to add into a dynamic menu def menu_func(self, context): default_path = os.path.splitext(bpy.data.filepath)[0] + ".cob" self.layout.operator(COBExporter.bl_idname, text="Compressed Object (.cob)").filepath = default_path def register(): bpy.utils.register_module(__name__) bpy.types.INFO_MT_file_export.append(menu_func) def unregister(): bpy.utils.unregister_module(__name__) bpy.types.INFO_MT_file_export.remove(menu_func) if __name__ == "__main__": register()