new python demo: car.py pyrit
authorRadek Brich <radek.brich@devl.cz>
Fri, 04 Apr 2008 01:55:25 +0200
branchpyrit
changeset 58 cfe98f5c0ae9
parent 57 1e92c21b9a61
child 59 64e456ab823d
new python demo: car.py new model format reader: LightWave lwo
demos/car.py
demos/lworeader.py
models/car/Nissan300ZX.lwo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/car.py	Fri Apr 04 01:55:25 2008 +0200
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+
+import sys
+sys.path.append(open('ModulePath').read().strip())
+
+from raytracer import Raytracer, Light, Sphere, Triangle, Material
+from lworeader import LoadLightwaveLwoFile
+import Image
+
+rt = Raytracer()
+mat = Material(colour=(0.9, 0.9, 0.9))
+LoadLightwaveLwoFile(rt, "../models/car/Nissan300ZX.lwo",	mat, smooth=True, scale=0.4) #, , trans=(0,-3,0))
+
+light = Light(position=(-5.0, 2.0, 8.0), colour=(0.2, 0.4, 0.6))
+rt.addlight(light)
+
+imagesize = (800, 600)
+data = rt.render(imagesize)
+img = Image.fromstring("RGB", imagesize, data)
+img.save('car.png')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/lworeader.py	Fri Apr 04 01:55:25 2008 +0200
@@ -0,0 +1,143 @@
+# LightWave .lwo file loader
+
+from struct import *
+from raytracer import Triangle, NormalVertex
+
+def read_int4(f):
+	return unpack('>i', f.read(4))[0]
+
+def read_int2(f):
+	return unpack('>h', f.read(2))[0]
+
+def read_float4(f):
+	return unpack('>f', f.read(4))[0]
+
+def read_string(f):
+	res = ''
+	b = f.read(1)
+	l = 1
+	while ( b != '\0' ):
+		res += b
+		b = f.read(1)
+		l += 1
+	if (l % 2 != 0):
+		f.read(1)
+		l += 1
+	return (res,l)
+
+def read_chunk(f):
+	ID = f.read(4)
+	if (ID == ''):
+		return ('',0)
+	size = read_int4(f)
+	return (ID, size)
+
+def read_subchunk(f):
+	ID = f.read(4)
+	size = read_int2(f)
+	return (ID, size)
+
+def read_lwo(filename):
+	points = []
+	faces = []
+	tags = []
+	surfaces = []
+	f = file(filename)
+	(ID,size) = read_chunk(f)
+	form = f.read(4)
+	if (ID != 'FORM' or form != 'LWOB'):
+		print 'not lwo file'
+		return
+	(ID,size) = read_chunk(f)
+	while (ID != ''):
+		#print ID,size
+		if (ID == 'PNTS'):
+			while (size > 0):
+				p1 = read_float4(f)
+				p2 = read_float4(f)
+				p3 = read_float4(f)
+				points.append((p1,p2,p3))
+				size -= 12
+		elif (ID == 'SRFS'):
+			while (size > 0):
+				(s,l) = read_string(f)
+				size -= l
+				tags.append(s)
+		elif (ID == 'POLS'):
+			while (size > 0):
+				vertex_count = read_int2(f)
+				size -= 2
+				inds = []
+				for i in range(vertex_count):
+					index = read_int2(f)
+					inds.append(index)
+					size -= 2
+				surf = read_int2(f)
+				size -= 2
+				faces.append((inds[0], inds[1], inds[2], surf))
+				i = 0
+				while (vertex_count > 3):
+					faces.append((inds[0], inds[2+i], inds[3+i], surf))
+					vertex_count -= 1
+					i += 1
+		elif (ID == 'SURF'):
+			(name,l) = read_string(f)
+			size -= l
+			surf = {}
+			while (size > 0):
+				(subID,subsize) = read_subchunk(f)
+				size -= 6
+				if (subID == 'COLR'):
+					col = f.read(subsize)
+					surf['color'] = (unpack('BBB',col[:3]))
+				else:
+					print "Warning:", subID,"("+str(subsize),"B) ignored"
+					f.read(subsize)
+				size -= subsize
+			surfaces.append(surf)
+		else:
+			print "Warning:", ID,"("+str(size),"B) ignored"
+			f.read(size)
+		(ID,size) = read_chunk(f)
+	return (points, faces, tags, surfaces)
+
+def LoadLightwaveLwoFile(rt, filename, defmat, smooth, scale=(1,1,1), trans=(0,0,0)):
+	if (type(scale) == float or type(scale) == int):
+		scale = (scale,)*3
+	(points, faces, tags, surfaces) = read_lwo(filename)
+
+	vertices = []
+	normals = []
+	vertex_face_num = []
+
+	for point in points:
+		v0 = scale[0]*point[0] + trans[0]
+		v1 = scale[1]*point[1] + trans[1]
+		v2 = scale[2]*point[2] + trans[2]
+		vertices.append(NormalVertex((v2,v1,v0)))
+		normals.append([0.,0.,0.])
+		vertex_face_num.append(0)
+
+
+	for f in faces:
+		v = [vertices[x] for x in f[0:3]]
+		surf = f[3]
+		mat = defmat
+		face = Triangle(v[0], v[1], v[2], mat)
+		n = face.getNormal()
+		for x in f[0:3]:
+			for i in range(3):
+				normals[x][i] += n[i]
+			vertex_face_num[x] += 1
+		if (smooth):
+			face.setSmooth()
+		rt.addshape(face)
+
+	# interpolate normals at vertices
+	num = 0
+	for vf in vertex_face_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
Binary file models/car/Nissan300ZX.lwo has changed