new space partitioning structure: octree
realtime_bunny updated to use octree
plus other files updated to be container type independent (only user programs are supposed to include and use special containers)
from raytracer import Triangle, NormalVertex
def LoadStanfordPlyFile(rt, filename, mat, smooth, scale=(1,1,1), trans=(0,0,0)):
if (type(scale) == float or type(scale) == int):
scale = (scale,)*3
vertices = []
normals = []
vertex_face_num = []
fp = file(filename)
# read header
tokens = (0,)
while (tokens[0] != "end_header"):
tokens = fp.readline().split()
if (tokens[0] == "element"):
if (tokens[1] == "vertex"):
vertex_num = int(tokens[2])
if (tokens[1] == "face"):
face_num = int(tokens[2])
# read vertices
num = vertex_num
while (num):
tokens = fp.readline().split()
v = [float(x) for x in tokens[0:3]]
v[0] = scale[0]*v[0] + trans[0]
v[1] = scale[1]*v[1] + trans[1]
v[2] = scale[2]*v[2] + trans[2]
vertices.append(NormalVertex(tuple(v)))
normals.append([0.,0.,0.])
vertex_face_num.append(0)
num -= 1
# read faces
while (face_num):
tokens = fp.readline().split()
if (tokens[0] != "3"):
print "ply warning: faces of %d vertices not supported" % tokens[0]
v = [vertices[int(x)] for x in tokens[1:4]]
face = Triangle(v[0], v[2], v[1], mat)
n = face.getNormal()
for x in tokens[1:4]:
for i in range(3):
normals[int(x)][i] += n[i]
vertex_face_num[int(x)] += 1
if (smooth):
face.setSmooth()
rt.addshape(face)
face_num -= 1
# interpolate normals at vertices
num = 0
while (num < vertex_num):
if (vertex_face_num[num] > 0):
for i in range(3):
normals[num][i] /= vertex_face_num[num]
vertices[num].setNormal(tuple(normals[num]))
num += 1