1import os, bpy, struct 2from bpy_extras.io_utils import ExportHelper 3from bpy.props import StringProperty, BoolProperty, EnumProperty 4 5# This is a custom Blender export script to output an object to a format that's easy to use in 6# android. While open gl allows the use of an index buffer for vertices, the same cannot be done 7# for texture coordinates, which is why this script duplicates the vertices and normals. This 8# gives a larger but faster loading file, hence the tongue-in-cheek name "Compressed" object file. 9# The format is number of vertices + list of vertices (3 coord, 3 normal, 2 texcoord) 10bl_info = { 11 "name": "COB Exporter", 12 "description": "Exports the active scene into a Compressed Object file.", 13 "author": "Stuart Scott", 14 "version": (1, 0, 0), 15 "blender": (2, 6, 2), 16 "api": 36339, 17 "location": "File > Export > COB Exporter (.cob)", 18 "warning": "", # used for warning icon and text in addons panel 19 "wiki_url": "", 20 "tracker_url": "", 21 "category": "Import-Export" 22 } 23 24class COBExporter(bpy.types.Operator, ExportHelper): 25 '''Exports the current scene into a Compressed Object format.''' 26 bl_idname = "export.cob_exporter" # this is important since its how bpy.ops.export.cob_exporter is constructed 27 bl_label = "COB Exporter" 28 29 filename_ext = ".cob" 30 31 filter_glob = StringProperty(default="*.cob", options={'HIDDEN'}) 32 33 def execute(self, context): 34 mesh = context.active_object 35 if mesh.type != 'MESH': 36 print("Active object is not a mesh") 37 return {'FINISHED'} 38 if mesh.mode != 'OBJECT': 39 bpy.ops.object.mode_set(mode='OBJECT', toggle=False) 40 print("Writing "+mesh.name+" to "+self.filepath) 41 uvtex = mesh.data.uv_textures.active # points to active texture 42 f = open(self.filepath, 'wb') 43 f.write(struct.pack(">i", len(uvtex.data) * 3))# write length 44 for uv_index, uv_itself in enumerate(uvtex.data): 45 # get uv for this face 46 uvs = uv_itself.uv1, uv_itself.uv2, uv_itself.uv3 47 for vertex_index, vertex_itself in enumerate(mesh.data.faces[uv_index].vertices): 48 # for each vertex in the face 49 vertex = mesh.data.vertices[vertex_itself] 50 v = vertex.co.xyz 51 n = vertex.normal.xyz 52 t = uvs[vertex_index] 53 f.write(struct.pack(">ffffffff", v[0], v[1], v[2], n[0], n[1], n[2], t[0], 1 - t[1])) 54 f.close() 55 return {'FINISHED'} 56 57 @classmethod 58 def poll(cls, context): 59 return context.active_object != None 60 61# Only needed if you want to add into a dynamic menu 62def menu_func(self, context): 63 default_path = os.path.splitext(bpy.data.filepath)[0] + ".cob" 64 self.layout.operator(COBExporter.bl_idname, text="Compressed Object (.cob)").filepath = default_path 65 66def register(): 67 bpy.utils.register_module(__name__) 68 bpy.types.INFO_MT_file_export.append(menu_func) 69 70def unregister(): 71 bpy.utils.unregister_module(__name__) 72 bpy.types.INFO_MT_file_export.remove(menu_func) 73 74if __name__ == "__main__": 75 register() 76