Created
April 28, 2019 19:42
-
-
Save dkorpel/52f7ef73adc06162c2bda6ea2acbb736 to your computer and use it in GitHub Desktop.
A Blender Python script to export meshes for OpenGL tinkering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Export script that takes the selected mesh and puts its vertex data (position, normal, uv) | |
# and indices of triangles on the clipboard and in the console | |
# | |
# > Why not just export to obj and read that? | |
# Proper obj reading requires you to deal with a lot of stuff: | |
# - separate indices for position, normal and uv, that need to be duplicated for an OpenGL VBO | |
# - 1-indexing | |
# - materials, objects, other things | |
# | |
# https://docs.blender.org/api/blender_python_api_2_73_release/bpy.types.MeshPolygon.html | |
# https://docs.blender.org/api/blender_python_api_2_73_release/bpy.types.MeshVertex.html | |
import bpy | |
from mathutils import Vector | |
obj = bpy.context.active_object | |
bpy.ops.object.mode_set(mode = 'EDIT') | |
bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY', ngon_method='BEAUTY') | |
bpy.ops.object.mode_set(mode = 'OBJECT') | |
separator = " " | |
datastr = "" ## Vertices:\n | |
# Convert a vector to a comma-separated string | |
def vecStr(vec, decimals=4): | |
result = "" | |
for i in vec: | |
result += str(round(i, decimals)) + separator | |
return result | |
uvlayer = obj.data.uv_layers.active | |
hasUv = uvlayer is not None # can be forced to True, then it will add 0,0 uv's if needed | |
nverts = len(obj.data.vertices) | |
nfaces = len(obj.data.polygons) | |
vertlists = [[] if hasUv else [Vector((0,0))] for i in range(nverts)] | |
faceSub = [[-1, -1, -1] for i in range(nfaces)] | |
for fn, face in enumerate(obj.data.polygons): | |
for vn, vid, loop in zip(range(3), face.vertices, face.loop_indices): | |
if hasUv: | |
uv = uvlayer.data[loop].uv | |
i = 0 | |
while i < len(vertlists[vid]): | |
if (vertlists[vid][i] == uv): | |
break | |
i+=1 | |
if i == len(vertlists[vid]): | |
vertlists[vid].append(uv) | |
faceSub[fn][vn] = i | |
else: | |
faceSub[fn][vn] = 0 | |
vertstart = [0 for i in range(nverts+1)] | |
for vn, vert in enumerate(obj.data.vertices): | |
vertstart[vn+1] = vertstart[vn] + len(vertlists[vn]) | |
if hasUv: | |
for uv in vertlists[vn]: | |
datastr += vecStr(vert.co) | |
datastr += vecStr(vert.normal) | |
datastr += vecStr(uv) | |
datastr += "\n" | |
pass | |
else: | |
datastr += vecStr(vert.co) | |
datastr += vecStr(vert.normal) | |
datastr += "\n" | |
datastr = str(vertstart[-1]) + separator + str(len(obj.data.polygons)) + "\n" + datastr | |
#datastr += "# Faces:\n" | |
for fn, face in enumerate(obj.data.polygons): | |
for i in range(3): | |
vn = face.vertices[i] | |
datastr += str(vertstart[vn] + faceSub[fn][i]) + separator | |
datastr += "\n" | |
print(datastr) | |
bpy.context.window_manager.clipboard = datastr |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment