From eef8b87899f310c9280823a0e34d7352bea4571c Mon Sep 17 00:00:00 2001 From: David Gavilan Date: Sun, 11 Nov 2012 23:08:57 +0900 Subject: [PATCH 1/3] Blender Export of textured models in Blender 2.64 --- .../io_export_objective_c_header.py | 314 ++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 Blender Export/objc_blend_2.64/io_export_objective_c_header.py diff --git a/Blender Export/objc_blend_2.64/io_export_objective_c_header.py b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py new file mode 100644 index 0000000..5036119 --- /dev/null +++ b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py @@ -0,0 +1,314 @@ +bl_info = { + "name": "Export Objective-C Header (.h)", + "author": "Jeff LaMarche", + "version": (1, 0), + "blender": (2, 5, 7), + "api": 35622, + "location": "File > Export", + "description": "Export Model to Objective-C Header file", + "warning": "", + "wiki_url": "", + "tracker_url": "", + "category": "Import-Export"} + +''' +Usage Notes: + + +''' + +import bpy +from bpy.props import * +import mathutils, math, struct +import os +from os import remove +import time +import bpy_extras +from bpy_extras.io_utils import ExportHelper +import time +import shutil +import bpy +import mathutils + +def triangulateNMesh(object): + bneedtri = False + scene = bpy.context.scene + bpy.ops.object.mode_set(mode='OBJECT') + for i in scene.objects: i.select = False #deselect all objects + object.select = True + scene.objects.active = object #set the mesh object to current + print("Checking mesh if needs to convert quad to Tri...") + object.data.update(calc_tessface=True) + for face in object.data.tessfaces: + if (len(face.vertices) > 3): + bneedtri = True + break + + bpy.ops.object.mode_set(mode='OBJECT') + if bneedtri == True: + print("Converting quad to tri mesh...") + me_da = object.data.copy() #copy data + me_ob = object.copy() #copy object + #note two copy two types else it will use the current data or mesh + me_ob.data = me_da + bpy.context.scene.objects.link(me_ob)#link the object to the scene #current object location + for i in scene.objects: i.select = False #deselect all objects + me_ob.select = True + scene.objects.active = me_ob #set the mesh object to current + bpy.ops.object.mode_set(mode='EDIT') #Operators + bpy.ops.mesh.select_all(action='SELECT')#select all the face/vertex/edge + bpy.ops.mesh.quads_convert_to_tris() #Operators + bpy.context.scene.update() + bpy.ops.object.mode_set(mode='OBJECT') # set it in object + print("Triangulate Mesh Done!") + print("Remove Merge tmp Mesh [ " ,object.name, " ] from scene!" ) + bpy.ops.object.mode_set(mode='OBJECT') # set it in object + bpy.context.scene.objects.unlink(object) + else: + print("No need to convert tri mesh.") + me_ob = object + return me_ob + + +def writeString(file, string): + file.write(bytes(string, 'UTF-8')) + +def do_export(context, props, filepath): + mat_x90 = mathutils.Matrix.Rotation(-math.pi/2, 4, 'X') + ob = context.active_object + me_ob = triangulateNMesh(ob) + current_scene = context.scene + apply_modifiers = props.apply_modifiers + + mesh = me_ob.to_mesh(current_scene, apply_modifiers, 'PREVIEW') + + basename = mesh.name.capitalize() + + if props.world_space: + mesh.transform(ob.matrix_world) + + if props.rot_x90: + mesh.transform(mat_x90) + + file = open(filepath, "wb") + theHeader = '//If not using MC3D, change 1 to 0 to add needed types\n#if 1\n\t#import "MC3DTypes.h"\n#else\n\ + struct texCoord\n\ + {\n\ + GLfloat u;\n\ + GLfloat v;\n\ + };\n\ + typedef struct texCoord texCoord;\n\ + typedef texCoord* texCoordPtr;\n\ +\n\ + typedef struct vec2 vec2;\n\ + typedef vec2* vec2Ptr;\n\ +\n\ + struct vec3\n\ + {\n\ + GLfloat x;\n\ + GLfloat y;\n\ + GLfloat z;\n\ + };\n\ +\n\ + typedef struct vec3 vec3;\n\ + typedef vec3* vec3Ptr;\n\ +\n\ + struct vec4\n\ + {\n\ + GLfloat x;\n\ + GLfloat y;\n\ + GLfloat z;\n\ + GLfloat w;\n\ + };\n\ +\n\ + typedef struct vec4 vec4;\n\ + typedef vec4* vec4Ptr;\n\ + \n\ +#endif\n\ +\n' + writeString(file, theHeader) + + if len(mesh.uv_textures) > 0: + writeString(file, 'struct vertexDataTextured\n\ +{\n\ + vec3 vertex;\n\ + vec3 normal;\n\ + texCoord texCoord;\n\ +}\n\ +typedef struct vertexDataTextured vertexDataTextured;\n\ +typedef vertexDataTextured* vertexDataTexturedPtr;\n\n\n') + writeString(file, 'static const vertexDataTextured %sVertexData[] = {\n' % basename) + #for face in uv: #loop through the faces + uv_layer = mesh.uv_textures.active + for face in mesh.tessfaces: + faceUV = uv_layer.data[face.index] + i=0 + for index in face.vertices: + if len(face.vertices) == 3: + vert = mesh.vertices[index] + writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) + writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z)) + writeString(file, '/*t:*/{%f, %f}' % ( faceUV.uv[i][0], faceUV.uv[i][1] ) ) + writeString(file, '},\n') + i+=1 + writeString(file, '};\n\n') + elif len(mesh.vertex_colors) > 0: + writeString(file, 'struct vertexDataColored\n\ +{\n\ + vec3 vertex;\n\ + vec3 normal;\n\ + vec4 color;\n\ +}\n\ +typedef struct vertexDataColored vertexDataColored;\n\ +typedef vertexDataColored* vertexDataColoredPtr;\n\n\n') + writeString(file, 'static const vertexDataColored %sVertexData[] = {\n' % basename) + color_layer = mesh.vertex_colors.active + for face in mesh.tessfaces: + if len(face.vertices) == 3: + faceC = color_layer.data[face.index] + i=0 + for index in face.vertices: + vert = mesh.vertices[index] + writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) + writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z)) + writeString(file, '/*c:*/{%f, %f, %f, %f}' % ( faceC.color1[i], faceC.color2[i], faceC.color3[i], faceC.color4[i]) ) + writeString(file, '},\n') + i+=1 + writeString(file, '};\n\n') + else: + writeString(file, 'struct vertexData\n\ +{\n\ + vec3 vertex;\n\ + vec3 normal;\n\ +}\n\ +typedef struct vertexData vertexData;\n\ +typedef vertexData* vertexDataPtr;\n\n\n') + writeString(file, 'static const vertexData %sVertexData[] = {\n' % basename) + for face in mesh.tessfaces: + if len(face.vertices) == 3: + for index in face.vertices: + vert = mesh.vertices[index] + writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) + writeString(file, '/*n:*/{%f, %f, %f} ' % (vert.normal.x, vert.normal.y, vert.normal.z)) + writeString(file, '},\n') + writeString(file, '};\n\n') + + writeString(file, '// Example OpenGL ES 1.1 Drawing Code:\n') + writeString(file, '// glEnableClientState(GL_VERTEX_ARRAY);\n') + if len(mesh.uv_textures) > 0: + writeString(file, '// glEnableClientState(GL_TEXTURE_COORD_ARRAY);\n') + elif len(mesh.vertex_colors) > 0: + writeString(file, '// glEnableClientState(GL_COLOR_ARRAY);\n') + writeString(file, '// glEnable(GL_COLOR_MATERIAL)\n') + writeString(file, '// glEnableClientState(GL_NORMAL_ARRAY);\n') + writeString(file, '// glVertexPointer(3, GL_FLOAT, sizeof(') + if len(mesh.uv_textures) > 0: + writeString(file, 'TexturedVertexData3D') + elif len(mesh.vertex_colors) > 0: + writeString(file, 'ColoredVertexData3D') + else: + writeString(file, 'VertexData3D') + writeString(file, '), &%sVertexData[0].vertex);\n' % basename) + writeString(file, '// glNormalPointer(GL_FLOAT, sizeof(') + if len(mesh.uv_textures) > 0: + writeString(file, 'TexturedVertexData3D') + elif len(mesh.vertex_colors) > 0: + writeString(file, 'ColoredVertexData3D') + else: + writeString(file, 'VertexData3D') + writeString(file, '), &%sVertexData[0].normal);\n' % basename) + if len(mesh.uv_textures) > 0: + writeString(file, '// glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &%sVertexData[0].texCoord);\n' % basename) + elif len(mesh.vertex_colors) > 0: + writeString(file, '// glColorPointer(4, GL_FLOAT, sizeof(ColoredVertexData3D), &%sVertexData[0].color);\n' % basename) + writeString(file, '// glDrawArrays(GL_TRIANGLES, 0, k%sNumberOfVertices);\n' % basename) + writeString(file, '// glDisableClientState(GL_VERTEX_ARRAY);\n') + if len(mesh.uv_textures) > 0: + writeString(file, '// glDisableClientState(GL_TEXTURE_COORD_ARRAY);\n') + elif len(mesh.vertex_colors) > 0: + writeString(file, '// glDisableClientState(GL_NORMAL_ARRAY);\n') + writeString(file, '// glDisable(GL_COLOR_MATERIAL);\n') + writeString(file, '// glDisableClientState(GL_NORMAL_ARRAY);\n\n\n') + + + file.flush() + file.close() + + return True + + +###### EXPORT OPERATOR ####### +class Export_objc(bpy.types.Operator, ExportHelper): + '''Exports the active Object as an Objective-C Header File.''' + bl_idname = "export_object.objc" + bl_label = "Export Objective-C Header (.h)" + + filename_ext = ".h" + + apply_modifiers = BoolProperty(name="Apply Modifiers", + description="Applies the Modifiers", + default=True) + + rot_x90 = BoolProperty(name="Convert to Y-up", + description="Rotate 90 degrees around X to convert to y-up", + default=True) + + world_space = BoolProperty(name="Export into Worldspace", + description="Transform the Vertexcoordinates into Worldspace", + default=False) + + + @classmethod + def poll(cls, context): + return context.active_object.type in ['MESH', 'CURVE', 'SURFACE', 'FONT'] + + def execute(self, context): + start_time = time.time() + print('\n_____START_____') + props = self.properties + filepath = self.filepath + filepath = bpy.path.ensure_ext(filepath, self.filename_ext) + + exported = do_export(context, props, filepath) + + if exported: + print('finished export in %s seconds' %((time.time() - start_time))) + print(filepath) + + return {'FINISHED'} + + def invoke(self, context, event): + wm = context.window_manager + + if True: + # File selector + wm.fileselect_add(self) # will run self.execute() + return {'RUNNING_MODAL'} + elif True: + # search the enum + wm.invoke_search_popup(self) + return {'RUNNING_MODAL'} + elif False: + # Redo popup + return wm.invoke_props_popup(self, event) # + elif False: + return self.execute(context) + + +### REGISTER ### + +def menu_func(self, context): + self.layout.operator(Export_objc.bl_idname, text="Objective-C Header (.h)") + +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() From 72ec5aae2368de7cd53ddf3086977fb66b94177d Mon Sep 17 00:00:00 2001 From: David Gavilan Date: Sun, 11 Nov 2012 23:14:10 +0900 Subject: [PATCH 2/3] Fixes the export of textured models in Blender 2.64 --- .../io_export_objective_c_header.py | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/Blender Export/objc_blend_2.64/io_export_objective_c_header.py b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py index 5036119..230f62f 100644 --- a/Blender Export/objc_blend_2.64/io_export_objective_c_header.py +++ b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py @@ -139,18 +139,31 @@ def do_export(context, props, filepath): typedef vertexDataTextured* vertexDataTexturedPtr;\n\n\n') writeString(file, 'static const vertexDataTextured %sVertexData[] = {\n' % basename) #for face in uv: #loop through the faces - uv_layer = mesh.uv_textures.active - for face in mesh.tessfaces: - faceUV = uv_layer.data[face.index] - i=0 - for index in face.vertices: - if len(face.vertices) == 3: - vert = mesh.vertices[index] - writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) - writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z)) - writeString(file, '/*t:*/{%f, %f}' % ( faceUV.uv[i][0], faceUV.uv[i][1] ) ) - writeString(file, '},\n') - i+=1 + #uv_layer = mesh.uv_layers.active + #for face in mesh.tessfaces: + # faceUV = uv_layer.data[face.index] + # i=0 + # for index in face.vertices: + # if len(face.vertices) == 3: + # vert = mesh.vertices[index] + # writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) + # writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z)) + # writeString(file, '/*t:*/{%f, %f}' % ( faceUV.uv[i][0], faceUV.uv[i][1] ) ) + # writeString(file, '},\n') + # i+=1 + # Print all the vertices using mesh.loops + uv_layer = mesh.uv_layers.active.data + for poly in mesh.polygons: + #writeString(file, "// Polygon index: %d, length: %d\n" % (poly.index, poly.loop_total)) + # range is used here to show how the polygons reference loops, + # for convenience 'poly.loop_indices' can be used instead. + for loop_index in range(poly.loop_start, poly.loop_start + poly.loop_total): + i=mesh.loops[loop_index].vertex_index + vert=mesh.vertices[i] + writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) + writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z) ) + writeString(file, '/*t:*/{%f, %f}' % ( uv_layer[loop_index].uv[0], uv_layer[loop_index].uv[1] ) ) + writeString(file, '},\n') writeString(file, '};\n\n') elif len(mesh.vertex_colors) > 0: writeString(file, 'struct vertexDataColored\n\ From 034af3d992e0f4d9b2ce8a44ca88107bcc2251ef Mon Sep 17 00:00:00 2001 From: David Gavilan Date: Mon, 4 Feb 2013 00:15:36 +0900 Subject: [PATCH 3/3] Fix normals --- .../objc_blend_2.64/io_export_objective_c_header.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Blender Export/objc_blend_2.64/io_export_objective_c_header.py b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py index 230f62f..cdc4a1f 100644 --- a/Blender Export/objc_blend_2.64/io_export_objective_c_header.py +++ b/Blender Export/objc_blend_2.64/io_export_objective_c_header.py @@ -161,7 +161,7 @@ def do_export(context, props, filepath): i=mesh.loops[loop_index].vertex_index vert=mesh.vertices[i] writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) - writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z) ) + writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.z, -vert.normal.y) ) writeString(file, '/*t:*/{%f, %f}' % ( uv_layer[loop_index].uv[0], uv_layer[loop_index].uv[1] ) ) writeString(file, '},\n') writeString(file, '};\n\n') @@ -182,8 +182,8 @@ def do_export(context, props, filepath): i=0 for index in face.vertices: vert = mesh.vertices[index] - writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.x, vert.co.y, vert.co.z) ) - writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.y, vert.normal.z)) + writeString(file, '\t{/*v:*/{%f, %f, %f}, ' % (vert.co.y, vert.co.z, vert.co.x) ) + writeString(file, '/*n:*/{%f, %f, %f}, ' % (vert.normal.x, vert.normal.z, -vert.normal.y)) writeString(file, '/*c:*/{%f, %f, %f, %f}' % ( faceC.color1[i], faceC.color2[i], faceC.color3[i], faceC.color4[i]) ) writeString(file, '},\n') i+=1