Что я должен поместить в имя файла в OBJFileLoader?

В OBJFileLoader, найденном по адресу https://www.pygame.org/wiki/OBJFileLoader, что я должен поставить вместо "имя файла".

В классе OBJ в строке: def init(self, filename, swapyz=False): когда я ввожу полный путь к файлу .obj, он говорит о неправильном синтаксисе.

Новое сообщение об ошибке:

Traceback (most recent call last):
 File "C:/Users/Winter/PycharmProjects/Plane/Plane.py", line 26, in <module>
    obj = OBJ('C:/Users/Winter/Desktop/TAL16OBJ.obj')
  File "C:\Users\Winter\PycharmProjects\Plane\Main.py", line 86, in __init__
    mtl = self.mtl[material]
AttributeError: 'OBJ' object has no attribute 'mtl'

Это текущий код:

import pygame
from OpenGL.GL import *

def MTL(filename):
    contents = {}
    mtl = None
    for line in open("C:/Users/Winter/Desktop/TAL16OBJ.mtl", "r"):
        if line.startswith('#'): continue
        values = line.split()
        if not values: continue
        if values[0] == 'newmtl':
            mtl = contents[values[1]] = {}
        elif mtl is None:
            raise ValueError("mtl file doesn't start with newmtl stmt")
        elif values[0] == 'map_Kd':
            # load the texture referred to by this declaration
            mtl[values[0]] = values[1]
            surf = pygame.image.load(mtl['map_Kd'])
            image = pygame.image.tostring(surf, 'RGBA', 1)
            ix, iy = surf.get_rect().size
            texid = mtl['texture_Kd'] = glGenTextures(1)
            glBindTexture(GL_TEXTURE_2D, texid)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                GL_LINEAR)
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                GL_LINEAR)
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ix, iy, 0, GL_RGBA,
                GL_UNSIGNED_BYTE, image)
        else:
            mtl[values[0]] = list(map(float, values[1:]))
    return contents

class OBJ:
    def __init__(self, filename, swapyz=False):
        """Loads a Wavefront OBJ file. """
        self.vertices = []
        self.normals = []
        self.texcoords = []
        self.faces = []

        material = None
        for line in open("C:/Users/Winter/Desktop/TAL16OBJ.obj", "r"):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values[0] == 'v':
                v = list(map(float, values[1:4]))
                if swapyz:
                    v = v[0], v[2], v[1]
                self.vertices.append(v)
            elif values[0] == 'vn':
                v = list(map(float, values[1:4]))
                if swapyz:
                    v = v[0], v[2], v[1]
                self.normals.append(v)
            elif values[0] == 'vt':
                self.texcoords.append(list(map(float, values[1:3])))
            elif values[0] in ('usemtl', 'usemat'):
                material = values[1]
            elif values[0] == 'mtllib':
                self.mtl = MTL(values[1])
            elif values[0] == 'f':
                face = []
                texcoords = []
                norms = []
                for v in values[1:]:
                    w = v.split('/')
                    face.append(int(w[0]))
                    if len(w) >= 2 and len(w[1]) > 0:
                        texcoords.append(int(w[1]))
                    else:
                        texcoords.append(0)
                    if len(w) >= 3 and len(w[2]) > 0:
                        norms.append(int(w[2]))
                    else:
                        norms.append(0)
                self.faces.append((face, norms, texcoords, material))

        self.gl_list = glGenLists(1)
        glNewList(self.gl_list, GL_COMPILE)
        glEnable(GL_TEXTURE_2D)
        glFrontFace(GL_CCW)
        for face in self.faces:
            vertices, normals, texture_coords, material = face

            mtl = self.mtl[material]
            if 'texture_Kd' in mtl:
                # use diffuse texmap
                glBindTexture(GL_TEXTURE_2D, mtl['texture_Kd'])
            else:
                # just use diffuse colour
                glColor(*mtl['Kd'])

            glBegin(GL_POLYGON)
            for i in range(len(vertices)):
                if normals[i] > 0:
                    glNormal3fv(self.normals[normals[i] - 1])
                if texture_coords[i] > 0:
                    glTexCoord2fv(self.texcoords[texture_coords[i] - 1])
                glVertex3fv(self.vertices[vertices[i] - 1])
            glEnd()
        glDisable(GL_TEXTURE_2D)
        glEndList()

from Main import *
import sys
import pygame
from pygame.locals import *
from pygame.constants import *
from OpenGL.GL import *
from OpenGL.GLU import *

pygame.init()
viewport = (800,600)
hx = viewport[0]/2
hy = viewport[1]/2
srf = pygame.display.set_mode(viewport, OPENGL | DOUBLEBUF)

glLightfv(GL_LIGHT0, GL_POSITION,  (-40, 200, 100, 0.0))
glLightfv(GL_LIGHT0, GL_AMBIENT, (0.2, 0.2, 0.2, 1.0))
glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1.0))
glEnable(GL_LIGHT0)
glEnable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)           # most obj files expect to be smooth-shaded

# LOAD OBJECT AFTER PYGAME INIT
obj = OBJ("C:/Users/Winter/Desktop/TAL16OBJ.obj")

clock = pygame.time.Clock()

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
width, height = viewport
gluPerspective(90.0, width/float(height), 1, 100.0)
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_MODELVIEW)

rx, ry = (0,0)
tx, ty = (0,0)
zpos = 5
rotate = move = False
while 1:
    clock.tick(30)
    for e in pygame.event.get():
        if e.type == QUIT:
            sys.exit()
        elif e.type == KEYDOWN and e.key == K_ESCAPE:
            sys.exit()
        elif e.type == MOUSEBUTTONDOWN:
            if e.button == 4: zpos = max(1, zpos-1)
            elif e.button == 5: zpos += 1
            elif e.button == 1: rotate = True
            elif e.button == 3: move = True
        elif e.type == MOUSEBUTTONUP:
            if e.button == 1: rotate = False
            elif e.button == 3: move = False
        elif e.type == MOUSEMOTION:
            i, j = e.rel
            if rotate:
                rx += i
                ry += j
            if move:
                tx += i
                ty -= j

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

    # RENDER OBJECT
    glTranslate(tx/20., ty/20., - zpos)
    glRotate(ry, 1, 0, 0)
    glRotate(rx, 0, 1, 0)
    glCallList(obj.gl_list)

person Manly Winter    schedule 29.11.2018    source источник
comment
Пожалуйста, покажите, как именно вы это называете   -  person    schedule 29.11.2018
comment
def __init__(self, C:/Users/Winter/Desktop/TAL16OBJ.obj, swapyz=False):   -  person Manly Winter    schedule 29.11.2018
comment
имя файла ожидает строку. То есть путь должен быть в кавычках   -  person    schedule 29.11.2018
comment
Все тот же результат.   -  person Manly Winter    schedule 29.11.2018
comment
Это не то, как использовать класс. Возможно, вы захотите посмотреть руководство для начинающих по Python.   -  person tkausl    schedule 29.11.2018
comment
Это происходит из этого: pygame.org/wiki/OBJFileLoader. Мне просто нужно знать, что я должен поместить в имя файла.   -  person Manly Winter    schedule 29.11.2018
comment
Не могли бы вы взглянуть на код с pygame.org/wiki/OBJFileLoader. Что-то не так с кодом, возможно, поэтому он не работает.   -  person Manly Winter    schedule 29.11.2018
comment
Возможный дубликат OBJFILELOADER — pygame   -  person skrx    schedule 29.11.2018
comment
Просто передайте путь/имя файла при создании экземпляра.   -  person skrx    schedule 29.11.2018
comment
Я покопался и обнаружил, что в другом потоке я узнал, что OBJLoader был написан для Python 2 и должен быть исправлен для Python 3. Итак, с учетом сказанного, я сделал это obj = OBJ('TAL16OBJ.obj'). Теперь ошибка: в init mtl = self.mtl[material] AttributeError: объект 'OBJ' не имеет атрибута 'mtl'.   -  person Manly Winter    schedule 29.11.2018
comment
Пожалуйста, опубликуйте полное сообщение об ошибке (вы можете добавить его к вопросу). И используете ли вы сейчас эту версию скрипта stackoverflow.com/a/47660960?   -  person skrx    schedule 29.11.2018
comment
Я обновил код по предоставленной вами ссылке и добавил новое сообщение об ошибке, которое я получаю к вопросу.   -  person Manly Winter    schedule 29.11.2018
comment
Кажется, у модели (файл .obj) нет материала. Откройте файл .obj и проверьте, начинается ли строка с mtllib.   -  person skrx    schedule 29.11.2018
comment
Это не так, я просто добавляю это?   -  person Manly Winter    schedule 29.11.2018
comment
Вы сами экспортировали модель? Затем назначьте материал модели в графическом редакторе и снова экспортируйте. Вам также потребуется файл .mtl, содержащий информацию о материале. Если он у вас уже есть, вы можете попробовать добавить mtllib NameOfYourMTLfile.mtl вверху файла .obj, но я не уверен, что это сработает.   -  person skrx    schedule 29.11.2018
comment
Итак, теперь я все исправил без сообщений об ошибках. Окно Pygame появляется без сбоев, просто файл obj не отображается. Это просто белый экран.   -  person Manly Winter    schedule 29.11.2018
comment
Добавьте свой текущий код в вопрос.   -  person skrx    schedule 29.11.2018
comment
Хорошо, я добавил самый последний код, который у меня есть.   -  person Manly Winter    schedule 29.11.2018


Ответы (1)


AttributeError: 'OBJ' object has no attribute 'mtl' было поднято, потому что в файле .obj отсутствовал материал. В верхней части файла .obj должна быть такая строка.

mtllib NameOfYourMTLfile.mtl 

указывает, какой файл материала/.mtl следует использовать для модели. Вероятно, модель была неправильно экспортирована.


Вы должны вызвать pygame.display.flip() внизу цикла while, чтобы обновить окно pygame.

while 1:
    # ... other code omitted.
    # Call this at the bottom of the loop.
    pygame.display.flip()

Кроме того, в функции MTL и классе OBJ вы должны передать переменную/параметр filename в open вместо этого строкового литерала "C:/Users/Winter/Desktop/TAL16OBJ.mtl".

def MTL(filename):
    contents = {}
    mtl = None
    for line in open(filename, "r"):  # open(filename)


class OBJ:
    def __init__(self, filename, swapyz=False):
        """Loads a Wavefront OBJ file. """
        self.vertices = []
        self.normals = []
        self.texcoords = []
        self.faces = []

        material = None
        for line in open(filename, "r"):  # open(filename)
person skrx    schedule 29.11.2018