from OpenGL.GL import * import string class WFObject: class wfface: def __init__(self): self.points = [] def draw(self): glBegin(GL_POLYGON) for p in self.points: glVertex3fv(p['v']) glEnd() class wfline: def __init__(self): self.points = [] def draw(self): glBegin(GL_LINE_STRIP) for p in self.points: glVertex3fv(p['v']) glEnd() class wfpoints: def __init__(self): self.points = [] def draw(self): glBegin(GL_POINTS) for p in self.points: glVertex3fv(p['v']) glEnd() class wfmaterial: def __init__(self): self.illum = 2 self.Kd = [1, 1, 1, 1] self.Ka = [0, 0, 0, 0] self.Ks = [0, 0, 0, 0] self.Ns = 0 self.texture = None def draw(self): glColor4fv(self.Kd) def __init__(self, filename=None): self.v = [] self.vn = [] self.vt = [] self.mtl = [] self.geometry = [] self.materials = {} self.displayListInitted = False if filename: self.loadFile(filename) def loadFile(self, filename): self.fileName = filename self.lineNum = 0 for line in open(filename, 'r').readlines(): self.lineNum += 1 values = string.split(line) if len(values) < 1: continue elif values[0] == 'v': self.parseVertex(values) elif values[0] == 'vn': self.parseNormal(values) elif values[0] == 'vt': self.parseTexCoord(values) elif (values[0] == 'f') or (values[0] == 'fo'): self.parseFace(values) elif values[0] == 'l': self.parseLine(values) elif values[0] == 'p': self.parsePoints(values) elif values[0] == 'mtllib': self.parseMtllib(values) elif values[0] == 'usemtl': self.parseUsemtl(values) def parseVertex(self, val): if len(val) < 4: print 'warning: incomplete vertex info:', self.fileName, 'line', self.lineNum self.v.append([0, 0, 0]) else: self.v.append([string.atof(val[1]), string.atof(val[2]), string.atof(val[3])]) def parseNormal(self, val): if len(val) < 4: print 'warning: incomplete normal info:', self.fileName, 'line', self.lineNum self.vn.append([0, 0, 0]) else: self.vn.append([string.atof(val[1]), string.atof(val[2]), string.atof(val[3])]) def parseTexCoord(self, val): if len(val) < 3: print 'warning: incomplete texcoord info:', self.fileName, 'line', self.lineNum self.vt.append([0, 0]) else: self.vt.append([string.atof(val[1]), string.atof(val[2])]) def parseFace(self, val): if len(val) < 4: return face = WFObject.wfface() face.points = self.parsePointList(val) self.geometry.append(face) def parseLine(self, val): if len(val) < 3: return line = WFObject.wfline() line.points = self.parsePointList(val) self.geometry.append(line) def parsePoints(self, val): if len(val) < 2: return pt = WFObject.wfpoints() pt.points = self.parsePointList(val) self.geometry.append(pt) def parsePointList(self, val): points = [] for v in val[1:]: p = { } data = string.split(v,'/') if len(data) > 0: index = string.atoi(data[0]) if index > 0: p['v'] = self.v[index-1] elif index < 0: p['v'] = self.v[len(self.v)+index] if len(data) > 1: index = string.atoi('0'+data[1]) if index > 0: p['vt'] = self.vt[index-1] elif index < 0: p['vt'] = self.vt[len(self.vt)+index] if len(data) > 2: index = string.atoi('0'+data[2]) if index > 0: p['vn'] = self.vn[index-1] elif index < 0: p['vn'] = self.vn[len(self.vn)+index] points.append(p) return points def parseMtllib(self, val): if len(val) < 2: return curmtl = WFObject.wfmaterial() for line in open(val[1]).readlines(): values = string.split(line) if len(values) < 1: continue if values[0] == 'newmtl': curmtl = WFObject.wfmaterial() if len(values) > 1: self.materials[values[1]] = curmtl elif values[0] == 'illum': if len(values) > 1: curmtl.illum = string.atoi(values[1]) elif values[0] == 'Ns': if len(values) > 1: curmtl.Ns = string.atof(values[1]) elif values[0] == 'Kd': if len(values) > 3: curmtl.Kd = [string.atof(values[1]), string.atof(values[2]), string.atof(values[3]), 1] elif values[0] == 'Ka': if len(values) > 3: curmtl.Ka = [string.atof(values[1]), string.atof(values[2]), string.atof(values[3]), 1] elif values[0] == 'Ks': if len(values) > 3: curmtl.Ks = [string.atof(values[1]), string.atof(values[2]), string.atof(values[3]), 1] elif values[0] == 'map_Kd': if len(values) > 1: curmtl.texture = Texture2D(values[1]) def parseUsemtl(self, val): if len(val) < 2: return self.geometry.append(self.materials[val[1]]) def draw(self): if not self.displayListInitted: self.displayList = glGenLists(1) glNewList(self.displayList, GL_COMPILE) for g in self.geometry: g.draw() glEndList() self.displayListInitted = True glCallList(self.displayList)