Gra_3d/obj_loader.py
2017-08-10 17:53:55 +02:00

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