Hatena::ブログ(Diary)

Andy Roid’s Memorandum

2017-10-16

blender to C++ exporter for vertices and normals of triangulated mesh for CULL_FACE

Modified so that the front-sides are directed in their normals.
(faces's normal. not vertex's normal)

import bpy

def cross(u, v):
    return [u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], u[1]*v[2]-u[2]*v[1]]
    
def dot(u, v):
    return u[0]*v[0]+u[1]*v[1]+u[2]*v[2]
    
def diff(u, v):
    return [u[0]-v[0], u[1]-v[1], u[2]-v[2]]

ao = bpy.context.active_object

lineNum = 0
f = open("Obj.cpp", "w")

# vertices
lineNum = 0
i = 0
l = []
f.write("GLfloat Obj::vtx_src[] = {\n")
for v in ao.data.vertices:
    i += 1
    n = v.normal
    f.write("%f, %f, %f,\n"% (v.co.x, v.co.y, v.co.z))
    if i%10 == 0:
        f.write("// line %d\n" %i)
        
f.write("};\n\n")

# normals
lineNum = 0
i = 0
l = []
f.write("GLfloat Obj::nml_src[] = {\n")
for v in ao.data.vertices:
    i += 1
    n = v.normal
    f.write("%f, %f, %f,\n"% (n.x, n.y, n.z))
    if i%10 == 0:
        f.write("// line %d\n" %i)
        
f.write("};\n\n")

#indices
lineNum = 0
i = 0
f.write("GLushort Obj::idx_src[] = {\n")
for p in ao.data.polygons:
    l = []
    n = p.normal
    for ek in p.edge_keys:
        for v in ek:
            if v.numerator not in l:
                l.append(v.numerator)
    vh = []
    for id in l:
        vh.append(ao.data.vertices[id].co)
    vv = cross(diff(vh[1], vh[0]), diff(vh[2],vh[0]))
    if dot(n, vv) < 0.0:
        l[1], l[2] = l[2], l[1]
    f.write("%d, %d, %d,\t"% (l[0], l[1], l[2]))
    i += 1
    if i%4 == 0:
        f.write("\n") 
        lineNum += 1
        if lineNum%10 == 0:
            f.write("// line %d\n" %lineNum)
        
f.write("};\n")

f.close()

2017-10-15

blender to C++ exporter for vertices and normals of triangulated mesh

If you prefer vertices/normals separated style, this is for you.

import bpy
ao = bpy.context.active_object

lineNum = 0
f = open("Obj.cpp", "w")

# vertices
lineNum = 0
i = 0
l = []
f.write("GLfloat Obj::vtx_src[] = {\n")
for v in ao.data.vertices:
    i += 1
    n = v.normal
    f.write("%f, %f, %f,\n"% (v.co.x, v.co.y, v.co.z))
    if i%10 == 0:
        f.write("// line %d\n" %i)
        
f.write("};\n\n")

# normals
lineNum = 0
i = 0
l = []
f.write("GLfloat Obj::nml_src[] = {\n")
for v in ao.data.vertices:
    i += 1
    n = v.normal
    f.write("%f, %f, %f,\n"% (n.x, n.y, n.z))
    if i%10 == 0:
        f.write("// line %d\n" %i)
        
f.write("};\n\n")

#indices
lineNum = 0
i = 0
f.write("GLushort Obj::idx_src[] = {\n")
for p in ao.data.polygons:
    l = []
    for ek in p.edge_keys:
        for v in ek:
            if v.numerator not in l:
                i += 1
                l.append(v.numerator)
                f.write("%d, "% v.numerator)
                if i%3 == 0:
                    f.write("\t") 
                    if i%12 == 0:
                        f.write("\n") 
                        lineNum += 1
                        if lineNum%10 == 0:
                            f.write("// line %d\n" %lineNum)
        
f.write("};\n")

f.close()

2017-10-14

blender to C++ exporter for vertices and normals of triangulated mesh

Use in vnvnvn way with OpenGL.

import bpy
ao = bpy.context.active_object

lineNum = 0
f = open("Obj.cpp", "w")

# vertices and normals
lineNum = 0
i = 0
l = []
f.write("GLfloat Obj::vtxnml_src[] = {\n")
for v in ao.data.vertices:
    i += 1
    n = v.normal
    f.write("%f, %f, %f, \t%f, %f, %f,\n"% (v.co.x, v.co.y, v.co.z, n.x, n.y, n.z))
    if i%10 == 0:
        f.write("// line %d\n" %i)
        
f.write("};\n\n")

#indices
lineNum = 0
i = 0
f.write("GLushort Obj::idx_src[] = {\n")
for p in ao.data.polygons:
    l = []
    for ek in p.edge_keys:
        for v in ek:
            if v.numerator not in l:
                i += 1
                l.append(v.numerator)
                f.write("%d, "% v.numerator)
                if i%3 == 0:
                    f.write("\t") 
                    if i%12 == 0:
                        f.write("\n") 
                        lineNum += 1
                        if lineNum%10 == 0:
                            f.write("// line %d\n" %lineNum)
        
f.write("};\n")

f.close()

2017-10-12

get edges for each MeshPolygon

ao = bpy.context.active_object

for p in ao.data.polygons:
     p
     for ek in p.edge_keys:
         ek

This results like

py.data.meshes['Plane'].polygons[0]
(2, 3)
(1, 3)
(0, 1)
(0, 2)
bpy.data.meshes['Plane'].polygons[1]
(0, 1)
(1, 5)
(4, 5)
(0, 4)
...

Note diagonal vertices do not share each other.

2017-09-13

simple text exporter of vertices for Blender Python for CPP

a small modification of the last snippet for C++.

import bpy
import bmesh

def up(lineNum, v, f):
    for e in v.link_edges:
        ov = e.other_vert(v)
        if ov not in verts:
            verts.append(ov)
            lineNum = up(lineNum, ov, f)
    if lineNum%10 == 0:
        f.write("// line %d\n" %lineNum)            
    f.write("%f, %f, %f,\n"% (v.co.x, v.co.y, v.co.z))
    return lineNum+1
    
def down(lineNum, v, f):
    if lineNum%10 == 0:
        f.write("// line %d\n" %lineNum)            
    f.write("%f, %f, %f,\n"% (v.co.x, v.co.y, v.co.z))
    for e in v.link_edges:
        ov = e.other_vert(v)
        if ov not in verts:
            verts.append(ov)
            lineNum = down(lineNum, ov, f)
    return lineNum+1
    
obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)

verts = []

def main():
    lineNum = 0
    f = open("Obj.cpp", "w")
    f.write("GLfloat Obj::vtx[] = {\n")
    v0 = bm.verts[0]
    verts.append(v0)
    e0 = v0.link_edges
    u = e0[0].other_vert(v0)
    verts.append(u)
    lineNum = up(lineNum, u, f)
    if lineNum%10 == 0:
        f.write("// line %d\n" %lineNum)            
    f.write("%f, %f, %f,\n"% (v0.co.x, v0.co.y, v0.co.z))
    lineNum += 1
    if len(e0)>1:
        d = e0[1].other_vert(v0)
        verts.append(d)
        lineNum = down(lineNum, d, f)
    f.write("};\n")
    f.close()