2

这是我的 QGLWidget 类,用于通过 openGL 绘制 3d 网格

class OpenGLWidget1(QGLWidget):

#def init(self,fdir,filename,swapyz=False):
    #self.fdir=fdir
    #self.filename=filename
    #self.swapyz=swapyz
    #self.initializeObj()

def initializeObj(self):

    self.vertices=[]
    self.normals=[]
    self.texcoords=[]
    self.faces=[]
    self.mtl=[self.fdir,"no_mtllib_file"]

    self.material="color0"

    for line in open(self.fdir+self.filename,"r"):
        if line.startswith('#'):continue
        values=line.split()
        if not values:continue
        if values[0] == 'v' :
            v=[float(values[1]),float(values[2]),float(values[3])]
            if self.swapyz:
                v = v[0],v[2],v[1]
            self.vertices.append(v)

        elif values[0] == 'vn':
            v=[float(values[1]),float(values[2]),float(values[3])]
            if self.swapyz:
                v = v[0],v[2],v[1]
            self.normals.append(v)

        elif values[0] == 'vt':
            v=[float(values[1]),float(values[2])]
            self.texcoords.append(v)

        elif values[0] == 'usemtl':
            self.material=values[1]

        elif values[0] == 'mtllib':
            self.mtl=[self.fdir,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,self.material))

def create_bbox(self):
    ps=np.array(self.vertices)
    vmin=ps.min(axis=0)
    vmax=ps.max(axis=0)

    self.bbox_center=(vmax+vmin)/2
    self.bbox_half_r=np.max(vmax-vmin)/2

def create_gl_list(self):
    self.mtl=MTL(*self.mtl)
    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]
        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()

def initializeGL(self):
    self.fdir = "/home/pczebra/pig9/outModel/"
    self.filename = "model101_out.obj"
    self.swapyz = True
    self.initializeObj()
    glViewport(0, 0, self.geometry().width(), self.geometry().height())
    self.create_bbox()
    light.setup_lighting()
    glLightfv(GL_LIGHT0,GL_POSITION,(0,0,-1000,0.0))
    glEnable(GL_DEPTH_TEST)
    glShadeModel(GL_SMOOTH)
    self.create_gl_list()
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()

    cam=light.camera
    cam.Ortho.bbox[:]=cam.Ortho.bbox * 13
    cam.Ortho.nf[:]=cam.Ortho.nf * 20
    glOrtho(*cam.Ortho.params)
    glEnable(GL_DEPTH_TEST)
    glMatrixMode(GL_MODELVIEW)

    self.rx,self.ry=(0,0)
    self.tx,self.ty=(0,0)
    self.zpos=5




def paintGL(self):

    #glViewport(0,0,self.geometry().width(),self.geometry().height())
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

    glTranslate(self.tx/20. , self.ty/20. , - self.zpos)
    glRotate(self.ry/5,1,0,0)
    glRotate(self.rx/5,0,0,1)

    s=[10/self.bbox_half_r]*3
    glScale(*s)

    t=-self.bbox_center
    glTranslate(*t)

    glCallList(self.gl_list)


def resizeGL(self, width, height):
    glViewport(0,0,width,height)

def mousePressEvent(self, QMouseEvent):
    if Qt.LeftButton == QMouseEvent.button():
        self.lastPos=QMouseEvent.pos()
    if Qt.RightButton == QMouseEvent.button():
        self.lastPos=QMouseEvent.pos()

def mouseMoveEvent(self, QMouseEvent):
    if QMouseEvent.buttons() and Qt.LeftButton:
        a=QMouseEvent.pos()
        dx=a.x()-self.lastPos.x()
        dy=a.y()-self.lastPos.y()

        dx=dx/2
        dy=dy/2

        self.rx -=dx
        self.ry -=dy

        self.updateGL()

    if QMouseEvent.buttons() and Qt.RightButton:
        a=QMouseEvent.pos()
        dx = a.x() - self.lastPos.x()
        dy = a.y() - self.lastPos.y()

        dx = dx / 2
        dy = dy / 20

        self.tx += dx
        self.ty -= dy

        self.updateGL()
    self.lastPos=QMouseEvent.pos()

然后我在 pyqt 中有两个 QGLWidget,用于即时上课

def w1(self):
    self.glWidget = OpenGLWidget1(self)
    self.glWidget.setGeometry(QRect(30, 540, 651, 401))
    self.glWidget.show()
def w2(self):
    self.glWidget_raw = OpenGLWidget1(self)
    #self.glWidget_raw.init(fdir,filename, swapyz=True)
    self.glWidget_raw.setGeometry(QRect(30, 50, 651, 401))
    self.glWidget_raw.show()
def visualization(self, checked):
    self.w1()
    self.w2()

并显示

运行结果图

第二个 QGLWidget 和后来的 QGLWidget 总是有 gl size 的问题,反正不能正常显示!我该如何解决这个问题。

4

1 回答 1

1
于 2018-11-01T10:39:50.347 回答