Skip to content

Instantly share code, notes, and snippets.

@dkorpel
Created April 28, 2019 19:42
Show Gist options
  • Save dkorpel/52f7ef73adc06162c2bda6ea2acbb736 to your computer and use it in GitHub Desktop.
Save dkorpel/52f7ef73adc06162c2bda6ea2acbb736 to your computer and use it in GitHub Desktop.
A Blender Python script to export meshes for OpenGL tinkering
# 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