GlExporter.py

import bpy
import math
import bmesh

# Supposing every object has a name which begins with one of
# followings: c_, s_, h_
# c_ stands for cylinder, s_ sphere and h_ hemisphere respectively.
# 2014 march 14 sphere is not yet implemented.

# index
def printIdx(idx, nIdx):
    nListLines = 1+floor(nIdx/10)
    print("nIdx = "+str(nIdx), "nListLines ="+str(nListLines))
    i = 0
    for j in range(nListLines):
        print("j= "+str(j))
        s = "\t"
        for k in range(10):
            if i < nIdx-1:
                s = s+str(idx[i])+", "
            elif i < nIdx:
                s = s+str(idx[i])
            else:
                break
            print("hi["+str(i)+"] = "+str(idx[i]))
            i += 1
        s += "\n"
        f.write(s)

def writeIdx(name, nVert):
    print("name="+name+" nVert="+str(nVert))
    f.write("const GLushort "+name+"_idx[] = {\n")
    if name.startswith('h_'):
        nLatitudes = floor(math.sqrt(float((nVert-1)/3)))
        print("nLatitudes="+str(nLatitudes))
        hi = list(hemisphereIdx(nLatitudes))
        print(hi)
        nIdx = len(hi)
        printIdx(hi, nIdx)
    elif name.startswith('c_'):
        header = name.split("_")
        # cylinder name: c_m_ObjectName
        m = int(header[1])
        n = int(nVert/m)
        print("m="+str(m), "n="+str(n))
        ci = list(cylinderIdx(m, n))
        nIdx=len(ci)
        printIdx(ci, nIdx)
    else:
        nIdx=0
    f.write("};\n\n")
    f.write("const GLint "+name+"_n_idx = "+str(nIdx)+";\n\n")

def printMeshes():
    for m in bpy.data.meshes:
        print(m.name)

def printObjects():
    for m in bpy.data.objects:
        print(m.name)

def hemisphereIdx(n):
#    for k in range(3*n*(n+1)):
#        yield(k, k+1)
    for p in range(n):
        # u0 = upper origin of p_th latitude
        # l0 = lower origin of p_th latitude (on p+1_th latitude)
        if p == 0:
            u0 = 0
        else:
            u0 = 1+3*p*(p-1)
        l0 = 1+3*p*(p+1)
        for q in range(6):
            # on q_th edge of p_th latitude
            # u, l are edge-origins
            u = u0+p*q
            l = l0+(p+1)*q
            # redundancy required
            yield(u)
            yield(l)
            for r in range(p):
                # r_th point on q_th edge of p_th latitude
                uu = u+r
                ll = l+r+1
                yield(uu)
                yield(ll)
        # for each latitude, last vtx should be the origin
        yield(u0)
        yield(l0)
    
def cylinderIdx(m, n):
    for y in range(n-1):
        for x in range(m):
            yield y*m + x
            yield (y+1)*m + x
        yield y*m
        yield (y+1)*m

f = open("glData.c", "w")
scn = bpy.context.scene
for o in scn.objects:
    if o.type != 'MESH':
        continue
    scn.objects.active = o
    bpy.ops.object.select_pattern(pattern=o.name)
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
#    bpy.ops.mesh.select_all(action='SELECT')
    m = o.data
    l = len(m.vertices)
    if l==0:
        continue
    f.write("\n////////// "+o.name+" //////////\n")
    f.write("const GLint "+o.name+"_n_vtx = "+str(l)+";\n")
    f.write("const GLfloat "+o.name+"_vtx[] = {\n")
    for n in range(l):
        if n % 10 == 0:
            f.write("\t// "+str(n)+"th vert\n")
        v = m.vertices[n]
        if n < l-1:
            f.write("\t"+str(v.co[0])
                +",\t"+str(v.co[1])
                +",\t"+str(v.co[2])+",\n")
        else:
            f.write("\t"+str(v.co[0])
                +",\t"+str(v.co[1])
                +",\t"+str(v.co[2])+"\n")
    f.write("};\n\n")
#
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
    bm = bmesh.from_edit_mesh(m)
    bpy.context.scene.objects.active = o
    uv_lay = bm.loops.layers.uv.active
#
    n = len(o.data.vertices)
    print("n = "+str(n))
    writeIdx(o.name, n)
#
    uv = {}
    nFaces = len(bm.faces)
    for face in bm.faces:
        for loop in face.loops:
            if uv_lay is not None:
                uv[loop.vert.index] = loop[uv_lay].uv
#
    n = len(uv)
    if n==0:
        f.write("const int "+o.name+"_hasTexture = 0;\n")
        continue
    f.write("const int "+o.name+"_hasTexture = 1;\n")
    f.write("const GLfloat "+o.name+"_uv[] = {\n")
    #index starts with 0
    for d in sorted(uv):
        if d % 10 == 0:
            f.write("\t// "+str(d)+"th vert\n")
        if d < n-1:
            f.write("\t"+str(uv[d][0])+",\t"+str(uv[d][1])+",\n")
        else:
            f.write("\t"+str(uv[d][0])+",\t"+str(uv[d][1])+"\n")
    f.write("};\n\n")
    
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
f.close()