118 lines
4.5 KiB
Python
118 lines
4.5 KiB
Python
from OpenGL.GL import *
|
|
from ctypes import *
|
|
import numpy as np
|
|
from math import *
|
|
class Object:
|
|
file=None
|
|
vertices=[]
|
|
normals=[]
|
|
faces=[]
|
|
materials=[]
|
|
lists=[]
|
|
r=[0,0,0]
|
|
texcoords=[]
|
|
def __init__(self,filename,pos,smoothnormals):
|
|
self.smoothnormals=smoothnormals
|
|
self.pos=pos
|
|
self.file=open(filename, 'r')
|
|
for line in self.file:
|
|
l=line.split()
|
|
if len(l)>0:
|
|
command=l[0]
|
|
words=l[1:]
|
|
if command=='v':
|
|
self.vertices.append((float(words[0]),float(words[1]),float(words[2])))
|
|
elif command=='vn':
|
|
self.normals.append((float(words[0]),float(words[1]),float(words[2])))
|
|
elif command=='vt':
|
|
self.texcoords.append((float(words[0]),float(words[1])))
|
|
elif command=='f':
|
|
if len(words)==3:
|
|
self.faces.append((int(words[0].split("/",2)[2])-1,\
|
|
int(words[0].split("/",2)[0])-1,\
|
|
int(words[1].split("/",2)[0])-1,\
|
|
int(words[2].split("/",2)[0])-1))
|
|
elif len(words)==4:
|
|
self.faces.append((int(words[0].split("/",2)[2])-1,\
|
|
int(words[0].split("/",2)[0])-1,\
|
|
int(words[1].split("/",2)[0])-1,\
|
|
int(words[2].split("/",2)[0])-1,\
|
|
int(words[3].split("/",2)[0])-1))
|
|
else:
|
|
print("Only Quads and Triangles are supported")
|
|
elif command=="mtllib":
|
|
filen=words[0]
|
|
f=open(filen, 'r')
|
|
for lin in f:
|
|
li=lin.split()
|
|
if len(li)>=1:
|
|
com=li[0]
|
|
other=li[1:]
|
|
if com=="newmtl":
|
|
name=other
|
|
else:
|
|
continue
|
|
self.file.close()
|
|
if self.smoothnormals:
|
|
nn=[]
|
|
for i in range(len(self.vertices)):
|
|
nn.append(None)
|
|
for i in range(len(self.vertices)):
|
|
vecX=0.0
|
|
vecY=0.0
|
|
vecZ=0.0
|
|
num=0
|
|
for face in self.faces:
|
|
for vertex in face[1:]:
|
|
if vertex==i:
|
|
vecX+=self.normals[face[0]][0]
|
|
vecY+=self.normals[face[0]][1]
|
|
vecZ+=self.normals[face[0]][2]
|
|
num+=1
|
|
if num>0:
|
|
vecX/=num
|
|
vecY/=num
|
|
vecZ/=num
|
|
d=sqrt(vecX*vecX+vecY*vecY+vecZ*vecZ)
|
|
if d>0:
|
|
vecX/=d
|
|
vecY/=d
|
|
vecZ/=d
|
|
nn[i]=(vecX,vecY,vecZ)
|
|
self.normals=nn
|
|
self.num=glGenLists(1)
|
|
glNewList(self.num,GL_COMPILE)
|
|
for face in self.faces:
|
|
if len(face)==5:
|
|
glBegin(GL_QUADS)
|
|
glNormal3fv(self.normals[face[1]])
|
|
glVertex3fv(self.vertices[face[1]])
|
|
glNormal3fv(self.normals[face[2]])
|
|
glVertex3fv(self.vertices[face[2]])
|
|
glNormal3fv(self.normals[face[3]])
|
|
glVertex3fv(self.vertices[face[3]])
|
|
glNormal3fv(self.normals[face[4]])
|
|
glVertex3fv(self.vertices[face[4]])
|
|
glEnd()
|
|
else:
|
|
glBegin(GL_TRIANGLES)
|
|
glNormal3fv(self.normals[face[1]])
|
|
glVertex3fv(self.vertices[face[1]])
|
|
glNormal3fv(self.normals[face[2]])
|
|
glVertex3fv(self.vertices[face[2]])
|
|
glNormal3fv(self.normals[face[3]])
|
|
glVertex3fv(self.vertices[face[3]])
|
|
glEnd()
|
|
glEndList()
|
|
def draw(self):
|
|
glPushMatrix()
|
|
glRotatef(self.r[0],1,0,0)
|
|
glRotatef(self.r[1],0,1,0)
|
|
glRotatef(self.r[2],0,0,1)
|
|
glTranslatef(self.pos[0],self.pos[1],self.pos[2])
|
|
glCallList(self.num)
|
|
glPopMatrix()
|
|
def rotate(self,x,y,z):
|
|
self.r[0]+=x
|
|
self.r[1]+=y
|
|
self.r[2]+=z |