def load(self,fname):
     mtllines = resource.location(fname).open(fname,"r")
     mname = None
     mat_dl = None
     mat_params = {'Ka':GL_AMBIENT, 'Kd': GL_DIFFUSE, 'Ks':GL_SPECULAR}
     tname = None
     for line in mtllines:
         tokens = line.split()
         if not tokens or line[0] == '#':
             continue
         if tokens[0] == 'newmtl':
             if mname:
                 if not tname: glDisable(GL_TEXTURE_2D)
                 glEndList()
             tname = None
             mname = tokens[1]
             mat_dl = self.mat_dls.get(mname)
             if mat_dl is None:
                 mat_dl = self.mat_dls[mname] = glGenLists(2)
             glNewList(mat_dl, GL_COMPILE)
         elif tokens[0] == 'Ns':
             glMaterialf(GL_FRONT, GL_SHININESS, float(tokens[1]))
         elif tokens[0] in mat_params:
             params = map(float,tokens[1:])
             floats4 = Mat4Floats(1.0,1.0,1.0,1.0)
             for i,f in enumerate(params):
                 floats4[i] = f
             self.mat_trans[mname] = (floats4[3] < 1.0)
             glMaterialfv(GL_FRONT, mat_params[tokens[0]],floats4)
         elif tokens[0] == 'map_Kd' and not NOTEXTURES:
             # need a texture
             glEnable(GL_TEXTURE_2D)
             glCallList(mat_dl+1) # will bind texture
             glEndList()
             tname = tokens[1]
             tex = resource.texture(tokens[1])
             glNewList(mat_dl+1,GL_COMPILE)
             if tex:
                 self.mat_textures[tname] = tex
                 trans = self.mat_trans.get(mname,False)
                 self.mat_trans[mname] = trans
                 glEnable(GL_TEXTURE_2D)
                 glBindTexture(GL_TEXTURE_2D,tex.id)
             # will end list before starting next one, or at end
     if mname:
         if not tname: glDisable(GL_TEXTURE_2D)
         glEndList()
    def load_obj(self,fname,swapyz=False,on_polygon=None):
        """ Load the .obj file, drawing each sub-object into a display
            list, and setting each material into a display list

            A piece called xxx_Origin has one vertex which marks the origin
            for piece 'xxx', and just adds a glTranslate before and
            after drawing 'xxx'.
        """
        objlines = resource.location(fname).open(fname,"r")
        self.origins = {}
        def int0(s):
            if s:
                return int(s)
            else:
                return 0
        piece = ''
        mesh_dl = None
        npoints = 0
        primitives = {1:GL_POINTS, 2: GL_LINES, 3:GL_TRIANGLES, 4:GL_QUADS}
        vertices = []
        normals = []
        tcoords = []
        for line in objlines:
            tokens = line.split()
            if not tokens or line[0] == '#':
                continue
            key = tokens[0]
            if key == 'mtllib':
                if self.mname:
                    self.mat_dls.load(self.mname)
                else:
                    self.mat_dls.load(tokens[1])
            elif key == 'o':
                if piece.endswith("_Origin") and len(vertices):
                    self.origins[piece[:-7]] = vertices[-1]
                elif npoints:
                    glEnd()
                    npoints = 0
                if mesh_dl:
                    glEndList()
                piece = tokens[1]
                if piece.endswith("_Origin"):
                    mesh_dl = None
                else:
                    mesh_dl = self.mesh_dls[piece] = glGenLists(1)
                    self.mesh_trans[piece] = False
                    glNewList(mesh_dl,GL_COMPILE)
            elif key == 'v':
                vx,vy,vz = map(float,tokens[1:4])
                if swapyz:
                    vx,vy,vz = vx,vz,vy
                vertices.append((vx,vy,vz))
            elif key == 'vn':
                normals.append(map(float,tokens[1:4]))
            elif key == 'vt':
                tcoords.append(map(float,tokens[1:3]))
            elif key == 'usemtl':
                if npoints:
                    glEnd()
                    npoints = 0
                mdl = self.mat_dls.get(tokens[1])
                if mdl is not None: # a material we have loaded
                    glCallList(mdl)
                    self.mesh_trans[piece] |= self.mat_dls.is_transparent(tokens[1])
            elif key == 'f':
                points = [map(int0, s.split('/'))
                          for s in tokens[1:]]
                if len(points) != npoints:
                    if npoints:
                        glEnd()
                    npoints = len(points)
                    prim = primitives.get(npoints, GL_POLYGON)
                    glBegin(prim)
                for v, t, n in points:
                    if n: glNormal3f(*normals[n-1])
                    if t: glTexCoord2f(*tcoords[t-1])
                    glVertex3f(*vertices[v-1])
                if on_polygon:
                    on_polygon(piece,[vertices[v-1] for v,t,n in points])
                if npoints > 4: # GL_POLYGON
                    npoints = -1 # can't continue without a glEnd()
        if piece.endswith("_Origin") and len(vertices):
            self.origins[piece[:-7]] = vertices[-1]
        elif npoints:
            glEnd()
            npoints = 0
        if mesh_dl:
            glEndList()
        # Now wrap extra glTranslatef around the pieces with origins
        for piece,(vx,vy,vz) in self.origins.items():
            dl_old = self.mesh_dls.get(piece)
            if not dl_old:
                continue
            dl_new = glGenLists(1)
            self.mesh_dls[piece] = dl_new
            self.mesh_dls[dl_old] = dl_old # stash it so __del__ can release it later
            with gl_compile(dl_new):
                glTranslatef(-vx,-vy,-vz)
                glCallList(dl_old)
                glTranslatef(vx,vy,vz)
Exemple #3
0
    def load_obj(self, fname, swapyz=False, on_polygon=None):
        """ Load the .obj file, drawing each sub-object into a display
            list, and setting each material into a display list

            A piece called xxx_Origin has one vertex which marks the origin
            for piece 'xxx', and just adds a glTranslate before and
            after drawing 'xxx'.
        """
        objlines = resource.location(fname).open(fname, "r")
        self.origins = {}

        def int0(s):
            if s:
                return int(s)
            else:
                return 0

        piece = ''
        mesh_dl = None
        npoints = 0
        primitives = {1: GL_POINTS, 2: GL_LINES, 3: GL_TRIANGLES, 4: GL_QUADS}
        vertices = []
        normals = []
        tcoords = []
        for line in objlines:
            tokens = line.split()
            if not tokens or line[0] == '#':
                continue
            key = tokens[0]
            if key == 'mtllib':
                if self.mname:
                    self.mat_dls.load(self.mname)
                else:
                    self.mat_dls.load(tokens[1])
            elif key == 'o':
                if piece.endswith("_Origin") and len(vertices):
                    self.origins[piece[:-7]] = vertices[-1]
                elif npoints:
                    glEnd()
                    npoints = 0
                if mesh_dl:
                    glEndList()
                piece = tokens[1]
                if piece.endswith("_Origin"):
                    mesh_dl = None
                else:
                    mesh_dl = self.mesh_dls[piece] = glGenLists(1)
                    self.mesh_trans[piece] = False
                    glNewList(mesh_dl, GL_COMPILE)
            elif key == 'v':
                vx, vy, vz = map(float, tokens[1:4])
                if swapyz:
                    vx, vy, vz = vx, vz, vy
                vertices.append((vx, vy, vz))
            elif key == 'vn':
                normals.append(map(float, tokens[1:4]))
            elif key == 'vt':
                tcoords.append(map(float, tokens[1:3]))
            elif key == 'usemtl':
                if npoints:
                    glEnd()
                    npoints = 0
                mdl = self.mat_dls.get(tokens[1])
                if mdl is not None:  # a material we have loaded
                    glCallList(mdl)
                    self.mesh_trans[piece] |= self.mat_dls.is_transparent(
                        tokens[1])
            elif key == 'f':
                points = [map(int0, s.split('/')) for s in tokens[1:]]
                if len(points) != npoints:
                    if npoints:
                        glEnd()
                    npoints = len(points)
                    prim = primitives.get(npoints, GL_POLYGON)
                    glBegin(prim)
                for v, t, n in points:
                    if n: glNormal3f(*normals[n - 1])
                    if t: glTexCoord2f(*tcoords[t - 1])
                    glVertex3f(*vertices[v - 1])
                if on_polygon:
                    on_polygon(piece, [vertices[v - 1] for v, t, n in points])
                if npoints > 4:  # GL_POLYGON
                    npoints = -1  # can't continue without a glEnd()
        if piece.endswith("_Origin") and len(vertices):
            self.origins[piece[:-7]] = vertices[-1]
        elif npoints:
            glEnd()
            npoints = 0
        if mesh_dl:
            glEndList()
        # Now wrap extra glTranslatef around the pieces with origins
        for piece, (vx, vy, vz) in self.origins.items():
            dl_old = self.mesh_dls.get(piece)
            if not dl_old:
                continue
            dl_new = glGenLists(1)
            self.mesh_dls[piece] = dl_new
            self.mesh_dls[
                dl_old] = dl_old  # stash it so __del__ can release it later
            with gl_compile(dl_new):
                glTranslatef(-vx, -vy, -vz)
                glCallList(dl_old)
                glTranslatef(vx, vy, vz)