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