QtOpenGL and other stuff

I’m playing around with QtOpenGL for kicks and giggles…

I’d like to render in my window viewport a selected object from maya’s viewport, with the first function “get_geo” processing the selected geometry and returning an array like so…

[[-5.73834228515625, -3.338400363922119, 4.355341911315918, 0.0, 0.0, 1.0, 0.375, 0.0], [more vert data after that], [etc…]]

where I get vertex position, normal, and uv data… for as many verts in the selection

anyhow I’m a little stumped on how to draw this array… at first the array wouldn’t be accepted unless I used a numPy array…


vertices = np.array([1, 1, -1, 1, -1, -1, 1, -1], dtype='float32')  # works but opted for the following

# vertices = np.array(get_geo()) # not working

vertices = [1, 1, -1, 1, -1, -1, 1, -1]
glBufferData(GL_ARRAY_BUFFER, len(vertices)*4, (c_float*len(vertices))(*vertices), GL_STATIC_DRAW)   #  numPy not required.. 

Anyhow I can’t get it to work with the array i’m passing from “get_geo”… as the above samples only deal with basic vertex position data…
any help in where I should look to solve this would be much appreciated!

also feel free to point out that I’m doing it all wrong… cheers!

below is the whole code snippit


import maya.cmds as cmds
import maya.OpenMayaUI as omui
import maya.OpenMaya as om
from shiboken import wrapInstance

import numpy as np
from ctypes import *

from PySide import QtGui
from PySide import QtOpenGL
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *


OBJ_NAME = 'myOpenGl'
WIN_TITLE = 'My Open GL Window'


def get_geo():
    """
    append vertex position, vertex normal, and uv data from selected geometry
    """

    selection = om.MSelectionList()
    om.MGlobal.getActiveSelectionList(selection)
    selection_iter = om.MItSelectionList(selection)

    obj = om.MObject()
    mVerts = om.MPointArray()
    mNorms = om.MFloatVectorArray()
    uArray = om.MFloatArray()
    vArray = om.MFloatArray()

    vert_array = []

    while not selection_iter.isDone():
        selection_iter.getDependNode(obj)
        dagPath = om.MDagPath.getAPathTo(obj)
        shape = om.MFnMesh(dagPath)

        shape.getPoints(mVerts)
        shape.getNormals(mNorms)

        shape.getUVs(uArray, vArray, shape.currentUVSetName())

        for x in range(mVerts.length()):
            vert_array.append([mVerts[x][0], mVerts[x][1], mVerts[x][2],
                               mNorms[x][0], mNorms[x][1], mNorms[x][2],
                               uArray[x], vArray[x]])

        selection_iter.next()

    return vert_array


def main_window():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtGui.QWidget)


def override(interface_class):
    def override(method):
        assert (method.__name__ in dir(interface_class))
        return method
    return override


class openGLWidget(QtOpenGL.QGLWidget):
    """
    Initialise openGl widget
    """

    @override(QtOpenGL.QGLWidget)
    def initializeGL(self):

        glClearColor(1, 1, 1, 1)  # white background
        glShadeModel(GL_SMOOTH)

        # create a VBO

        self.vbo = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)

        # vertices = np.array(get_geo())

        vertices = [1, 1, -1, 1, -1, -1, 1, -1]
        glBufferData(GL_ARRAY_BUFFER, len(vertices)*4, (c_float*len(vertices))(*vertices), GL_STATIC_DRAW)



        glEnable(GL_COLOR_MATERIAL)
        glMaterialfv(GL_FRONT, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
        glMaterialfv(GL_FRONT, GL_SHININESS, [50.0])
        glLightfv(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0])
        glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])
        glLightfv(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [1.0, 1.0, 1.0, 0.0])
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        self.orientCamera()
        gluLookAt(0, 0, -10,  # camera
                  0, 0, 0,  # focus
                  0, 1, 0)  # up vector'''

    @override(QtOpenGL.QGLWidget)
    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self.draw_geometry()

    @override(QtOpenGL.QGLWidget)
    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)
        self.orientCamera()

    def orientCamera(self):
        glPushAttrib(GL_TRANSFORM_BIT)  # remember current GL_MATRIX_MODE
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(60.0, self.width() / float(self.height()), 1.0, 10.0)
        glPopAttrib()  # restore GL_MATRIX_MODE

    def draw_geometry(self):
        """
        draw geometry
        """


        glPushAttrib(GL_POLYGON_BIT)  # remember current GL_FRONT_FACE indicator
        glFrontFace(GL_CW)  # teapot polygon vertex order is opposite to modern convention

        glClear(GL_COLOR_BUFFER_BIT)
        glEnableClientState(GL_VERTEX_ARRAY)

        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glVertexPointer(2, GL_FLOAT, 0, None)

        glColor3f(0.5, 0.0, 1.0)
        glDrawArrays(GL_QUADS, 0, 8)

        # glutSolidTeapot(3.0)
        # glutSolidCube(3.0)
        glPopAttrib()  # restore GL_FRONT_FACE


class openGlTestApp(QtGui.QMainWindow):
    """
    Make main window here
    """

    def __init__(self, parent=None):
        super(openGlTestApp, self).__init__(parent)

        self.setObjectName(OBJ_NAME)
        self.setWindowTitle(WIN_TITLE)
        self.resize(400, 400)

        container = QtGui.QWidget(self)
        self.setCentralWidget(container)
        layout = QtGui.QVBoxLayout(container)

        gl_area = openGLWidget()

        run_button = QtGui.QPushButton('push Me!')
        run_button.clicked.connect(get_geo)

        layout.addWidget(gl_area)
        layout.addWidget(run_button)

if __name__ == "__main__":
    if cmds.window(OBJ_NAME, q=True, exists=True):
        cmds.deleteUI(OBJ_NAME)

    global gui
    gui = openGlTestApp(main_window())
    gui.show()
    openGlTestApp()