PyQt5 Как повернуть трехмерный объект в отображаемом виджете? - PullRequest
0 голосов
/ 04 февраля 2020

Мне нужно вращать 3D-объекты с помощью ползунков в PyQt5. Я могу отобразить пользовательский куб или импортированные файлы 3d me sh, но не могу связать вращение с помощью ползунков. Я работал над примером и пытался вращать куб с помощью ползунков. Я добавил ползунки, добавил куб, я могу получить значение ползунка с помощью метода «печать». Но не могу повернуть коробку. Ниже приведен мой код:

'' '

from PyQt5 import QtCore      # core Qt functionality
from PyQt5 import QtGui       # extends QtCore with GUI functionality
from PyQt5 import QtOpenGL    # provides QGLWidget, a special OpenGL QWidget
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import OpenGL.GL as gl        # python wrapping of OpenGL
from OpenGL import GLU        # OpenGL Utility Library, extends OpenGL functionality

import sys                    # we'll need this later to run our Qt application
from OpenGL.arrays import vbo
import numpy as np


class Window(QtWidgets.QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("gl box")
        self.setGeometry(0, 0, 300, 300)
        self.glWidget = GLWidget
        self.initGUI()
        timer = QtCore.QTimer(self)
        timer.setInterval(20)  # period, in milliseconds
        timer.timeout.connect(self.glWidget.updateGL)
        timer.start()
    def initGUI(self):

        glWidget = GLWidget(self)

        self.s1 = QSlider(Qt.Horizontal)
        self.s1.valueChanged.connect(lambda val: glWidget.setRotX(val))
        self.s1.setMaximum(90)
        self.s1.setMinimum(0)
        self.s2 = QSlider(Qt.Horizontal)
        self.s2.valueChanged.connect(lambda val: glWidget.setRotY(val))
        self.s2.setMaximum(90)
        self.s2.setMinimum(0)
        self.s3 = QSlider(Qt.Horizontal)
        self.s3.valueChanged.connect(lambda val: glWidget.setRotZ(val))
        self.s3.setMaximum(90)
        self.s3.setMinimum(0)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(glWidget)
        layout.addWidget((self.s1))
        layout.addWidget((self.s2))
        layout.addWidget((self.s3))

        self.glWidget = GLWidget(self)
        # self.initGUI()
        self.show()

class GLWidget(QtOpenGL.QGLWidget):
    def __init__(self, parent=None):
        self.parent = parent
        QtOpenGL.QGLWidget.__init__(self, parent)

    def initializeGL(self):
        self.qglClearColor(QtGui.QColor(0, 0, 255))  # initialize the screen to blue
        gl.glEnable(gl.GL_DEPTH_TEST)  # enable depth testing

        self.initGeometry()

        self.rotX = 0.0
        self.rotY = 0.0
        self.rotZ = 0.0

    def resizeGL(self, width, height):
        gl.glViewport(0, 0, width, height)
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadIdentity()
        aspect = width / float(height)

        GLU.gluPerspective(45.0, aspect, 1.0, 100.0)
        gl.glMatrixMode(gl.GL_MODELVIEW)

    def paintGL(self):
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

        gl.glPushMatrix()  # push the current matrix to the current stack

        gl.glTranslate(0.0, 0.0, -50.0)  # third, translate cube to specified depth
        gl.glScale(20.0, 20.0, 20.0)  # second, scale cube
        #gl.glRotated(30, 0.5, 0.0, 0.0)
        gl.glRotated(self.rotX, 1.0, 0.0, 0.0)
        gl.glRotated(self.rotY, 0.0, 1.0, 0.0)
        gl.glRotated(self.rotZ, 0.0, 0.0, 1.0)
        gl.glTranslate(-0.5, -0.5, -0.5)  # first, translate cube center to origin


        gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
        gl.glEnableClientState(gl.GL_COLOR_ARRAY)

        gl.glVertexPointer(3, gl.GL_FLOAT, 0, self.vertVBO)
        gl.glColorPointer(3, gl.GL_FLOAT, 0, self.colorVBO)

        gl.glDrawElements(gl.GL_QUADS, len(self.cubeIdxArray), gl.GL_UNSIGNED_INT, self.cubeIdxArray)

        gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
        gl.glDisableClientState(gl.GL_COLOR_ARRAY)

        gl.glPopMatrix()  # restore the previous modelview matrix

    def initGeometry(self):
        self.cubeVtxArray = np.array(
            [[0.0, 0.0, 0.0],
             [1.0, 0.0, 0.0],
             [1.0, 1.0, 0.0],
             [0.0, 1.0, 0.0],
             [0.0, 0.0, 1.0],
             [1.0, 0.0, 1.0],
             [1.0, 1.0, 1.0],
             [0.0, 1.0, 1.0]])
        self.vertVBO = vbo.VBO(np.reshape(self.cubeVtxArray,
                                          (1, -1)).astype(np.float32))
        self.vertVBO.bind()

        self.cubeClrArray = np.array(
            [[0.0, 0.0, 0.0],
             [1.0, 0.0, 0.0],
             [1.0, 1.0, 0.0],
             [0.0, 1.0, 0.0],
             [0.0, 0.0, 1.0],
             [1.0, 0.0, 1.0],
             [1.0, 1.0, 1.0],
             [0.0, 1.0, 1.0]])
        self.colorVBO = vbo.VBO(np.reshape(self.cubeClrArray,
                                           (1, -1)).astype(np.float32))
        self.colorVBO.bind()

        self.cubeIdxArray = np.array(
            [0, 1, 2, 3,
             3, 2, 6, 7,
             1, 0, 4, 5,
             2, 1, 5, 6,
             0, 3, 7, 4,
             7, 6, 5, 4])
    def getMesh(self):
        theMesh = mesh.Mesh.from_file('C:\\Users\metet\Desktop\Yeni klasör\\menger.stl')
        p, q, r = theMesh.vectors.shape

        vertices, ixr = np.unique(theMesh.vectors.reshape(p * q, r), return_inverse=True, axis=0)
        I = np.take(ixr, [3 * k for k in range(p)])
        J = np.take(ixr, [3 * k + 1 for k in range(p)])
        K = np.take(ixr, [3 * k + 2 for k in range(p)])
        x, y, z = self.vertices.T
        print(I)

    def setRotX(self, val):
        self.rotX = np.pi * val
        print(val)

    def setRotY(self, val):
        self.rotY = np.pi * val

    def setRotZ(self, val):
        self.rotZ = np.pi * val


app = QtWidgets.QApplication(sys.argv)
w = Window()
app.exec_()
sys.exit()

' ''

И есть ли еще пример вращения меня sh (не куб)?

...