Example #1
0
class mainWindow(QMainWindow):  #Main class.
    shapes = [
    ]  #place all instaces of shapes in this list in order to have them rendered.
    dataPoints = []
    zoomLevel = -5
    rotateDegreeV = -90
    rotateDegreeH = 0
    marchActive = False
    limit = 0.5
    meshPoints = []
    step = 0
    pairs = [(0, 1), (0, 3), (0, 4), (2, 1), (2, 3), (2, 6), (7, 3), (7, 4),
             (7, 6), (5, 1), (5, 4), (5, 6)]

    def __init__(self):
        super(mainWindow, self).__init__()
        self.currentStep = 0
        self.width = 700  #Variables used for the setting of the size of everything
        self.height = 600
        self.setGeometry(0, 0, self.width + 50,
                         self.height + 25)  #Set the window size
        self.initData()
        self.shapes.append(cube((0, 0, 0)))
        self.shapes.append(cube((0, -1, 0)))
        for i in range(12):
            locA = locByVal(self.pairs[i][0])
            locB = locByVal(self.pairs[i][1])
            loc = (float(avg(
                (locA[0], locB[0]))), float(avg(
                    (locA[1], locB[1]))), float(avg((locA[2], locB[2]))))
            shape = cube(loc, 0.05, False, True, (1, 0, 0))
            self.meshPoints.append(shape)
            self.shapes.append(shape)
            #print(loc)

    def setupUI(self):
        self.openGLWidget = QOpenGLWidget(self)  #Create the GLWidget
        self.openGLWidget.setGeometry(0, 0, self.width, self.height)
        self.openGLWidget.initializeGL()
        self.openGLWidget.resizeGL(
            self.width, self.height
        )  #Resize GL's knowledge of the window to match the physical size?
        self.openGLWidget.paintGL = self.paintGL  #override the default function with my own?

        self.marchButton = QPushButton(self)
        self.marchButton.setGeometry(350, self.height, 60, 25)
        self.marchButton.setText('Step 0')
        self.marchButton.clicked.connect(self.cycle)

        self.readout = QLabel(self)
        self.readout.setGeometry(240, self.height, 110, 25)
        self.readout.setText("[0, 0, 0, 0, 0, 0, 0, 0]")

        self.indicators = []
        for i in range(8):
            indicator = QWidget(self)
            indicator.setGeometry(i * 30, self.height, 25, 25)
            indicator.setStyleSheet("background-color: blue;")
            self.indicators.append(indicator)

    def initData(self):
        for i in range(8):
            loc = locByVal(i)
            col = (0, 0.5, 0.5)
            shape = cube(location=loc,
                         drawWires=False,
                         drawFaces=True,
                         color=col)
            dp = dataPoint(location=loc, value=0.5, shape=shape)
            self.dataPoints.append(dp)
            self.shapes.append(dp.shape)

    def paintGL(self):
        glLoadIdentity()
        gluPerspective(45, self.width / self.height, 0.1,
                       110.0)  #set perspective?
        glTranslatef(
            0, 0,
            self.zoomLevel)  #I used -10 instead of -2 in the PyGame version.
        glRotatef(self.rotateDegreeV, 1, 0,
                  0)  #I used 2 instead of 1 in the PyGame version.
        glRotatef(self.rotateDegreeH, 0, 0, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        if len(self.shapes) != 0:
            glBegin(GL_LINES)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawWires:
                    for e in s.edges:
                        for v in e:
                            glVertex3fv(s.vertices[v])
            glEnd()

            glBegin(GL_QUADS)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawFaces:
                    for f in s.facets:
                        for v in f:
                            glVertex3fv(s.vertices[v])
            glEnd()

    def keyPressEvent(
        self, event
    ):  #This is the keypress detector. I use this to determine input to edit grids.
        try:
            key = event.key()
            #print(key)
            if key == 87:
                self.nav(rotV=5)
            elif key == 65:
                self.nav(rotH=5)
            elif key == 83:
                self.nav(rotV=-5)
            elif key == 68:
                self.nav(rotH=-5)
            elif key == 67:
                self.nav(zoomVal=1)
            elif key == 88:
                self.nav(zoomVal=-1)
            elif key == 82:
                self.cycle('up')
            elif key == 70:
                self.cycle('down')
        except:
            pass

    def nav(self, zoomVal=0, rotV=0, rotH=0):
        self.zoomLevel += zoomVal
        self.rotateDegreeV += rotV
        self.rotateDegreeH += rotH
        self.openGLWidget.update()

    def filter(self, value):
        self.limit = rnd((value / 49.5) - 1, -2)
        for d in self.dataPoints:
            if d.value < self.limit:
                d.shape.hide()
            else:
                d.shape.show()
        self.limitDisplay.setText(str(self.limit))
        self.openGLWidget.update()

    def getDP(self, coord):
        x, y, z = coord
        #print(self.dataPoints)
        #print('requested coordinates: {}'.format(coord))
        for dp in self.dataPoints:
            #print('dataPoint.location: {}'.format(dp.location))
            if dp.location == (x, y, z):
                return dp
        return False

    def cycle(self, dir='up'):
        #housekeeping
        if dir == 'up':
            if self.step == 255:
                self.step = 0
            else:
                self.step += 1
        elif dir == 'down':
            if self.step == 0:
                self.step = 255
            else:
                self.step -= 1

        #set the points
        self.marchButton.setText("Step " + str(self.step))
        binDat = intToBin(self.step)
        self.readout.setText(str(binDat))
        for dp in self.dataPoints:
            dp.shape.recolor((0, 0.5, 0.5))
        for indi in self.indicators:
            indi.setStyleSheet("background-color: blue;")
        for i in range(8):
            rawDat = binDat[7 - i]
            dat = (rawDat - 0.5) * 2  #0 --> -1  1 --> 1
            self.dataPoints[i].set(dat)
            self.dataPoints[i].shape.recolor((0, rawDat, 1 - rawDat))
            if dat == 1:
                self.indicators[7 -
                                i].setStyleSheet("background-color: green;")

        #show/hide the meshPoints
        for i in range(12):
            pointA = self.dataPoints[self.pairs[i][0]]
            pointB = self.dataPoints[self.pairs[i][1]]
            if pointA.value != pointB.value:
                self.meshPoints[i].show()
            else:
                self.meshPoints[i].hide()

        self.openGLWidget.update()
Example #2
0
class mainWindow(QMainWindow):  #Main class.
    shapes = [
    ]  #place all instances of shapes in this list in order to have them rendered.
    dataPoints = []
    zoomLevel = -10
    rotateDegreeV = -90
    rotateDegreeH = 0
    marchActive = False
    limit = -1.0
    meshPoints = []
    animationActive = False
    anLoops = 0
    printConfigs = False
    dataFieldSize = (3, 3, 3)

    def keyPressEvent(self, event):  #This is the keypress detector.
        try:
            key = event.key()
        except:
            key = -1
        #print(key)
        if key == 87:
            self.nav(vVal=5)
        elif key == 65:
            self.nav(hVal=5)
        elif key == 83:
            self.nav(vVal=-5)
        elif key == 68:
            self.nav(hVal=-5)
        elif key == 67:
            self.nav(zVal=1)
        elif key == 88:
            self.nav(zVal=-1)
        elif key == 77:
            self.marchStep()
        elif key == 16777216:
            exit()
        elif key == 16777235:
            self.filter(0.1)
        elif key == 16777237:
            self.filter(-0.1)

    def __init__(self, mode):
        super(mainWindow, self).__init__()
        self.opMode = mode
        self.currentStep = 0
        if self.opMode == 'show':
            self.sizeX = self.screen().size().width(
            )  #Variables used for the setting of the size of everything
            self.sizeY = self.screen().size().height()
        elif self.opMode == 'config':
            self.sizeX = 500
            self.sizeY = 500
            self.setGeometry(0, 0, self.sizeX + 50,
                             self.sizeY)  #Set the window size
        self.initData(self.dataFieldSize)
        self.setupUI()
        if self.opMode == 'show':
            self.animateStep()

    def setupUI(self):
        self.openGLWidget = QOpenGLWidget(self)  #Create the GLWidget
        self.openGLWidget.setGeometry(0, 0, self.sizeX, self.sizeY)
        self.openGLWidget.initializeGL()
        self.openGLWidget.resizeGL(
            self.sizeX, self.sizeY
        )  #Resize GL's knowledge of the window to match the physical size?
        self.openGLWidget.paintGL = self.paintGL  #override the default function with my own?

        if self.opMode != 'show':
            self.filterSlider = QSlider(Qt.Vertical, self)
            self.filterSlider.setGeometry(self.sizeX + 10,
                                          int(self.sizeY / 2) - 100, 30, 200)
            self.filterSlider.valueChanged[int].connect(self.barFilter)

            self.limitDisplay = QLabel(self)
            self.limitDisplay.setGeometry(self.sizeX,
                                          int(self.sizeY / 2) - 130, 50, 30)
            self.limitDisplay.setAlignment(Qt.AlignCenter)
            self.limitDisplay.setText('-1')

            self.marchButton = QPushButton(self)
            self.marchButton.setGeometry(self.sizeX,
                                         int(self.sizeY / 2) - 160, 50, 30)
            self.marchButton.setText('March!')
            self.marchButton.clicked.connect(self.marchStep)

    def initData(self, fieldSize):
        sizeX, sizeY, sizeZ = fieldSize
        marchSizeX = sizeX - 1
        marchSizeY = sizeY - 1
        marchSizeZ = sizeZ - 1
        xOff = -(sizeX / 2) + 0.5
        yOff = -(sizeY / 2) + 0.5
        zOff = -(sizeZ / 2) + 0.5
        xMarchOff = -(marchSizeX / 2) + 0.5
        yMarchOff = -(marchSizeY / 2) + 0.5
        zMarchOff = -(marchSizeZ / 2) + 0.5
        self.marchPoints = []
        for z in range(marchSizeZ):
            for y in range(marchSizeY):
                for x in range(marchSizeX):
                    self.marchPoints.append(
                        (x + xMarchOff, y + yMarchOff, z + zMarchOff))

        for z in range(sizeZ):
            for y in range(sizeY):
                for x in range(sizeX):
                    val = generate(x + xOff, y + yOff, z + zOff)
                    dpColor = (0, (val + 1) / 2, (val + 1) / -2 + 1)
                    dpShape = cube((x + xOff, y + yOff, z + zOff),
                                   drawWires=False,
                                   drawFaces=True,
                                   color=dpColor)
                    dp = dataPoint((x + xOff, y + yOff, z + zOff), val,
                                   dpShape)
                    self.dataPoints.append(dp)
                    self.shapes.append(dpShape)

    def marchStep(self):
        #print(self.currentStep)
        if not self.marchActive:  #initialize
            marchAddr = len(self.shapes)
            self.marchingCube = cube(size=1)
            self.shapes.append(self.marchingCube)
            self.marchActive = True
            self.currentStep = 0
            self.mainMesh = mesh()
            self.shapes.append(self.mainMesh)

        if self.currentStep == len(self.marchPoints):  #1 step after last
            self.marchingCube.hide()
            self.currentStep += 1
            for mp in self.meshPoints:
                mp.shape.hide()
            self.meshPoints = []
            self.openGLWidget.update()
            return
        if self.currentStep == len(self.marchPoints) + 1:  #2 steps after last
            #print('meshPoints: {}'.format(self.meshPoints))
            for mp in self.meshPoints:
                #print(mp.shape)
                self.shapes.remove(mp.shape)
            self.meshPoints.clear()
            self.shapes.remove(self.mainMesh)
            self.meshes = []
            self.currentStep = -1
            self.openGLWidget.update()
            return

        if self.currentStep == -1:  #1 step before first
            self.marchingCube.hide()
            self.currentStep += 1
            #print('self.meshPoints: {}\nself.meshes: {}\nself.shapes: {}'.format(self.meshPoints, self.meshes, self.shapes))
            self.openGLWidget.update()
            self.mainMesh = mesh()
            self.shapes.append(self.mainMesh)
            return

        self.marchingCube.show()
        p = self.marchPoints[self.currentStep]
        x, y, z = p
        self.marchingCube.move((x, y, z))
        points = []
        for i in range(8):
            #print(self.marchingCube.vertices[i])
            point = self.getDataPointByLocation(self.marchingCube.vertices[i])
            points.append(point)

        #place meshpoints and highlight the active ones.
        MPs = []
        for pair in self.marchingCube.wires:
            pointA = points[pair[0]]
            pointB = points[pair[1]]
            #print('pointA.value: {}  pointB.value: {}  limit: {}'.formatpointA.value, pointB.value, self.limit)
            xA, yA, zA = pointA.location
            xB, yB, zB = pointB.location
            valA = (pointA.value + 1) / 2
            valB = (pointB.value + 1) / 2
            xC = float(avg([xA, xB]))
            yC = float(avg([yA, yB]))
            zC = float(avg([zA, zB]))

            mp = meshPoint()
            mp.place(xC, yC, zC)
            mp.setShape(
                cube(size=0.05,
                     drawWires=False,
                     drawFaces=True,
                     color=(1, 0, 0)))
            mp.shape.move((xC, yC, zC))
            self.shapes.append(mp.shape)
            self.meshPoints.append(mp)
            MPs.append(mp)
            if (pointA.value < self.limit and pointB.value > self.limit) or (
                    pointA.value > self.limit and pointB.value < self.limit):
                mp.setActive(True)
            else:
                mp.setActive(False)

        activeConfig = 0
        for i in range(8):
            if points[i].value > self.limit:
                activeConfig += int(2**i)
        oldConfig = activeConfig
        if activeConfig > 127:
            activeConfig = 255 - activeConfig
        if self.printConfigs:
            print('Old configuration number: {}\nConfiguration number: {}'.
                  format(oldConfig, activeConfig))

        config = table[activeConfig]
        if self.printConfigs:
            print('Configuration: {}\nnumber of points: {}'.format(
                config, len(MPs)))
        for data in config:
            a, b, c = data
            locA = MPs[a].location
            locB = MPs[b].location
            locC = MPs[c].location
            self.mainMesh.addFacet((locA, locB, locC))
        self.currentStep += 1
        self.openGLWidget.update()

    def nav(self, hVal=0, vVal=0, zVal=0):
        self.zoomLevel += zVal
        self.rotateDegreeH += hVal
        self.rotateDegreeV += vVal
        self.openGLWidget.update()

    def barFilter(self, value):
        self.limit = rnd((value / 49.5) - 1, -2)
        for d in self.dataPoints:
            if d.value < self.limit:
                d.shape.hide()
            else:
                d.shape.show()
        self.limitDisplay.setText(str(self.limit))
        self.openGLWidget.update()

    def filter(self, value):
        self.limit += value
        self.limit = float(rnd(self.limit, -2))
        for d in self.dataPoints:
            if d.value < self.limit:
                d.shape.hide()
            else:
                d.shape.show()
        if self.opMode != 'show':
            self.limitDisplay.setText(str(self.limit))
        #print(self.limit)
        self.openGLWidget.update()

    def paintGL(self):
        #This function uses shape objects, such as cube() or mesh(). Shape objects require the following:
        #a list named 'vertices' - This list is a list of points, from which edges and faces are drawn.
        #a list named 'wires'    - This list is a list of tuples which refer to vertices, dictating where to draw wires.
        #a list named 'facets'   - This list is a list of tuples which refer to vertices, ditating where to draw facets.
        #a bool named 'render'   - This bool is used to dictate whether or not to draw the shape.
        #a bool named 'drawWires' - This bool is used to dictate whether wires should be drawn.
        #a bool named 'drawFaces' - This bool is used to dictate whether facets should be drawn.

        glLoadIdentity()
        gluPerspective(45, self.sizeX / self.sizeY, 0.1,
                       110.0)  #set perspective?
        glTranslatef(
            0, 0,
            self.zoomLevel)  #I used -10 instead of -2 in the PyGame version.
        glRotatef(self.rotateDegreeV, 1, 0,
                  0)  #I used 2 instead of 1 in the PyGame version.
        glRotatef(self.rotateDegreeH, 0, 0, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        if len(self.shapes) != 0:
            glBegin(GL_LINES)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawWires:
                    for w in s.wires:
                        for v in w:
                            glVertex3fv(s.vertices[v])
            glEnd()

            glBegin(GL_QUADS)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawFaces:
                    for f in s.facets:
                        for v in f:
                            glVertex3fv(s.vertices[v])
            glEnd()

    def getDataPointByLocation(self, coord):
        x, y, z = coord
        #print(self.dataPoints)
        #print('requested coordinates: {}'.format(coord))
        for dp in self.dataPoints:
            #print('dataPoint.location: {}'.format(dp.location))
            if dp.location == (x, y, z):
                return dp
        return False

    def animateStep(self):
        if not self.animationActive:
            self.animationTimer = QTimer()
            self.animationTimer.start(1000)
            self.animationTimer.timeout.connect(self.animateStep)
            self.nav(hVal=-15, vVal=20, zVal=-2)
            self.animationActive = True
            self.limit = 0
            self.filter(0)

        if self.currentStep == -1:
            #print('current shapes: {}'.format(len(self.shapes)))
            numMarchingCubes = 0
            numMainMeshes = 0
            cycles = 0
            removedShapes = 0
            keptShapes = 0
            #            for s in self.shapes:
            #               if s == self.marchingCube:
            #                  numMarchingCubes += 1
            #             if s == self.mainMesh:
            #                numMainMeshes += 1
            #           if s != self.marchingCube and s != self.mainMesh:
            #              removedShapes += 1
            #             self.shapes.remove(s)
            #        else:
            #           keptShapes += 1
            #      cycles += 1
            # print('cycled through {} shapes\nremoved {} shapes\n kept {} shapes\nremaining shapes: {}\nnumber of marchingCubes: {}\nnumber of mainMeshes: {}'.format(cycles, removedShapes, keptShapes, len(self.shapes), numMarchingCubes, numMainMeshes))
            self.shapes = [self.marchingCube]
            print("\n\nself.shapes: {}\nself.meshPoints: {}".format(
                self.shapes, self.meshPoints))
            self.dataPoints = []
            self.initData(self.dataFieldSize)
            self.filter(0)
            self.anLoops += 1


#            if self.anLoops == 2:
#               self.animationTimer.stop()
#              exit()

        self.marchStep()
        self.nav(hVal=2)
Example #3
0
class ThwackerMainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.Setup()

    def ReadVmf(self,vmf):
        keyvalueRootObject = demezkeyvalue.ReadFile('./test.vmf')
        worldValues = keyvalueRootObject.GetItem('world')
        if worldValues:
            solidList = worldValues.GetAllItems("solid")
            if solidList:
                for solid in solidList:
                    sideList = solid.GetAllItems("side")
                    for side in sideList:
                        sidePlane = side.GetItemValue('plane')
                        vert = []
                        for vertVal in sidePlane.split():
                            print(vertVal)
                            vert.append(0.01*int(vertVal.replace('(','').replace(')','')))
                            if len(vert) == 3:
                                self.VMFVerts.append(vert)
                                vert = []

        print(self.VMFVerts)
        
    def Setup(self):
        self.setWindowTitle("Thwacker")
        self.setWindowIcon(QIcon())

        self.setMinimumSize(QSize(750,500))

        #ContentSections
        self.Content = QGroupBox()
        self.ContentLayout = QGridLayout()

        # ToolBar
        ToolsToolBar = QToolBar('Tools')
        self.Tools = self.addToolBar(Qt.LeftToolBarArea,ToolsToolBar)

        #OpenGl
        self.GlViewport = QOpenGLWidget()
        self.GlViewport.initializeGL()
        self.GlViewport.paintGL = self.paintGL
        self.GlViewport.initializeGL = self.initializeGL

        self._glTimer = QBasicTimer()
        self._glTimer.start(1000/60, self)

        self.VMFVerts = []
        self.ReadVmf('./test.vmf')
        
        self.ContentLayout.addWidget(self.GlViewport,0,0)
        gluPerspective(45, self.width()/self.height(), 0.1, 50)

        self.Triangle = self.VMFVerts
        self.Indices = [] ;
        for i in range(len(self.VMFVerts)): self.Indices.append(i)
        

        self.Content.setLayout(self.ContentLayout)
        QApplication.setStyle(QStyleFactory.create('Cleanlooks'))
        self.setCentralWidget(self.Content)
        self.showMaximized()
        self.update()

    def resizeEvent(self,event):
        gluPerspective(45, self.width()/self.height(), 0.1, 50)

    def initializeGL(self):
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glEnable(GL_DEPTH_TEST)


    def paintGL(self):
        gluPerspective(45, self.width()/self.height(), 0.1, 50)
        glViewport(0, 0, self.GlViewport.width(), self.GlViewport.height())
        gluLookAt(12, 12, 12, 0, 0, 0, 0, 1, 0)

        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        glClear(GL_COLOR_BUFFER_BIT)

        glRotatef(90,1,0,0)

        glBegin(GL_TRIANGLES)

        for i in self.Indices:
            glVertex3fv(self.Triangle[i])

        glEnd()
        glFinish()
    
    def timerEvent(self, QTimerEvent):
        self.GlViewport.update()
Example #4
0
class mainWindow(QMainWindow):    #Main class.
    shapes = []    #place all instaces of shapes in this list in order to have them rendered.
    dataPoints = []
    zoomLevel = -10
    rotateDegreeV = -90
    rotateDegreeH = 0
    marchActive = False
    limit = -1
    meshPoints = []
    meshSectors = []
    
    def keyPressEvent(self, event):    #This is the keypress detector.
        try:
            key = event.key()
        except:
            key = -1    
        #print(key)
        if key == 87:
            self.rotateV(5)
        elif key == 65:
            self.rotateH(5)
        elif key == 83:
            self.rotateV(-5)
        elif key == 68:
            self.rotateH(-5)
        elif key == 67:
            self.zoom(1)
        elif key == 88:
            self.zoom(-1)
        elif key == 77:
            self.marchStep()
            
    def __init__(self):
        super(mainWindow, self).__init__()
        self.currentStep = 0
        self.width = 700    #Variables used for the setting of the size of everything
        self.height = 600
        self.setGeometry(0, 0, self.width + 50, self.height)    #Set the window size
        self.initData(4, 4, 4)

    def setupUI(self):
        self.openGLWidget = QOpenGLWidget(self)    #Create the GLWidget
        self.openGLWidget.setGeometry(0, 0, self.width, self.height)
        self.openGLWidget.initializeGL()
        self.openGLWidget.resizeGL(self.width, self.height)    #Resize GL's knowledge of the window to match the physical size?
        self.openGLWidget.paintGL = self.paintGL    #override the default function with my own?

        self.filterSlider = QSlider(Qt.Vertical, self)
        self.filterSlider.setGeometry(self.width + 10, int(self.height / 2) - 100, 30, 200)
        self.filterSlider.valueChanged[int].connect(self.filter)
        
        self.limitDisplay = QLabel(self)
        self.limitDisplay.setGeometry(self.width, int(self.height / 2) - 130, 50, 30)
        self.limitDisplay.setAlignment(Qt.AlignCenter)
        self.limitDisplay.setText('-1')

        self.marchButton = QPushButton(self)
        self.marchButton.setGeometry(self.width, int(self.height / 2) - 160, 50, 30)
        self.marchButton.setText('March!')
        self.marchButton.clicked.connect(self.marchStep)

    def initData(self, sizeX, sizeY, sizeZ):
        marchSizeX = sizeX - 1
        marchSizeY = sizeY - 1
        marchSizeZ = sizeZ - 1
        xOff = -(sizeX / 2) + 0.5
        yOff = -(sizeY / 2) + 0.5
        zOff = -(sizeZ / 2) + 0.5
        xMarchOff = -(marchSizeX / 2) + 0.5
        yMarchOff = -(marchSizeY / 2) + 0.5
        zMarchOff = -(marchSizeZ / 2) + 0.5
        self.marchPoints = []
        for z in range(marchSizeZ):
            for y in range(marchSizeY):
                for x in range(marchSizeX):
                    self.marchPoints.append((x + xMarchOff, y + yMarchOff ,z + zMarchOff))

        for z in range(sizeZ):
            for y in range(sizeY):
                for x in range(sizeX):
                    val = self.generate(x + xOff, y + yOff, z + zOff)
                    dpColor = (0, (val + 1) / 2, (val + 1) / -2 + 1)
                    dpShape = cube((x + xOff, y + yOff, z + zOff), drawWires = False, drawFaces = True, color = dpColor)
                    dp = dataPoint((x + xOff, y + yOff, z + zOff), val, dpShape)
                    self.dataPoints.append(dp)
                    self.shapes.append(dpShape)

    def paintGL(self):
        #This function uses shape objects, such as cube() or meshSector(). Shape objects require the following:
        #a list named 'vertices' - This list is a list of points, from which edges and faces are drawn.
        #a list named 'wires'    - This list is a list of tuples which refer to vertices, dictating where to draw wires.
        #a list named 'facets'   - This list is a list of tuples which refer to vertices, ditating where to draw facets.
        #a bool named 'render'   - This bool is used to dictate whether or not to draw the shape.
        #a bool named 'drawWires' - This bool is used to dictate whether wires should be drawn.
        #a bool named 'drawFaces' - This bool is used to dictate whether facets should be drawn.
        
        glLoadIdentity()
        gluPerspective(45, self.width / self.height, 0.1, 110.0)    #set perspective?
        glTranslatef(0, 0, self.zoomLevel)    #I used -10 instead of -2 in the PyGame version.
        glRotatef(self.rotateDegreeV, 1, 0, 0)    #I used 2 instead of 1 in the PyGame version.
        glRotatef(self.rotateDegreeH, 0, 0, 1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        
        if len(self.shapes) != 0:
            glBegin(GL_LINES)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawWires:
                    for w in s.wires:
                        for v in w:
                            glVertex3fv(s.vertices[v])
            glEnd()
        
            glBegin(GL_QUADS)
            for s in self.shapes:
                glColor3fv(s.color)
                if s.render and s.drawFaces:
                    for f in s.facets:
                        for v in f:
                            glVertex3fv(s.vertices[v])
            glEnd()

    def marchStep(self):
        print(self.currentStep)
        if not self.marchActive:    #initialize
            marchAddr = len(self.shapes)
            self.marchingCube = cube(size = 1)
            self.shapes.append(self.marchingCube)
            self.marchActive = True
            self.currentStep = 0

        if self.currentStep == len(self.marchPoints):    #1 step after last
            self.marchingCube.hide()
            self.currentStep += 1
            for mp in self.meshPoints:
                mp.shape.hide()
            self.meshPoints = []
            self.openGLWidget.update()
            return
        if self.currentStep == len(self.marchPoints) + 1:    #2 steps after last
            #print('meshPoints: {}'.format(self.meshPoints))
            for mp in self.meshPoints:
                #print(mp.shape)
                self.shapes.remove(mp.shape)
            self.meshPoints.clear()
            for shape in self.shapes:
                if shape in self.meshSectors:
                    self.shapes.remove(shape)
            self.meshSectors = []
            self.currentStep = -1
            self.openGLWidget.update()
            return
            
        if self.currentStep == -1:    #1 step before first
            self.marchingCube.hide()
            self.currentStep += 1
            print('self.meshPoints: {}\nself.meshSectors: {}\nself.shapes: {}'.format(self.meshPoints, self.meshSectors, self.shapes))
            self.openGLWidget.update()
            return
            
        self.marchingCube.show()
        p = self.marchPoints[self.currentStep]
        x, y, z = p
        self.marchingCube.move((x, y, z))
        points = []
        for i in range(8):
            #print(self.marchingCube.vertices[i])
            point = self.getDataPointByLocation(self.marchingCube.vertices[i])
            points.append(point)
        
        #place meshpoints and highlight the active ones.
        MPs = []
        for pair in self.marchingCube.wires:
            pointA = points[pair[0]]
            pointB = points[pair[1]]
            #print('pointA.value: {}  pointB.value: {}  limit: {}'.formatpointA.value, pointB.value, self.limit)
            xA, yA, zA = pointA.location
            xB, yB, zB = pointB.location
            valA = (pointA.value + 1) / 2
            valB = (pointB.value + 1) / 2
            xC = float(avg([xA, xB]))
            yC = float(avg([yA, yB]))
            zC = float(avg([zA, zB]))
                
            mp = meshPoint()
            mp.place(xC, yC, zC)
            mp.setShape(cube(size = 0.05, drawWires = False, drawFaces = True, color = (1, 0, 0)))
            mp.shape.move((xC, yC, zC))
            self.shapes.append(mp.shape)
            self.meshPoints.append(mp)
            MPs.append(mp)
            if (pointA.value < self.limit and pointB.value > self.limit) or (pointA.value > self.limit and pointB.value < self.limit):
                mp.setActive(True)
            else:
                mp.setActive(False)
                
        activeConfig = 0
        sector = meshSector()
        self.meshSectors.append(sector)
        self.shapes.append(sector)
        
        for i in range(8):
            if points[i].value > self.limit:
                activeConfig += int(2 ** i)
        print('Configuration number: {}'.format(activeConfig))
        if activeConfig > 127:
            activeConfig = 255 - activeConfig
        print('Configuration number: {}'.format(activeConfig))
        
        config = table[activeConfig]
        print('Configuration: {}'.format(config))
        print('number of points: {}'.format(len(MPs)))
        for data in config:
            a, b, c = data
            locA = MPs[a].location
            locB = MPs[b].location
            locC = MPs[c].location
            sector.addFacet((locA, locB, locC))

        print('stepping')
        self.currentStep += 1
        self.rotateH(0)

    def zoom(self, value):
        self.zoomLevel += value
        self.openGLWidget.update()

    def rotateV(self, value):
        self.rotateDegreeV += value
        self.openGLWidget.update()

    def rotateH(self, value):
        self.rotateDegreeH += value
        self.openGLWidget.update()
        
    def filter(self, value):
        self.limit = rnd((value / 49.5) -1, -2)
        for d in self.dataPoints:
            if d.value < self.limit:
                d.shape.hide()
            else:
                d.shape.show()
        self.limitDisplay.setText(str(self.limit))
        self.openGLWidget.update()

    def getDataPointByLocation(self, coord):
        x, y, z = coord
        #print(self.dataPoints)
        #print('requested coordinates: {}'.format(coord))
        for dp in self.dataPoints:
            #print('dataPoint.location: {}'.format(dp.location))
            if dp.location == (x, y, z):
                return dp
        return False

    def generate2(self, xIn, yIn, zIn):
        if xIn == 0 and yIn == 0 and zIn == 0:
            return 0.5
        return -0.5
        
    def generate(self, xIn, yIn, zIn):    #Function which produces semi-random values based on the supplied coordinates.
        i = -int(xIn * yIn * (10 + zIn))
        j = int(xIn * yIn * (10 + zIn))
        if i < j:
            mixer = random.randint(i, j + 1)
        else:
            mixer = random.randint(j, i + 1)
        a = avg([sin(cos(xIn)), tan(tan(yIn)), cos(tan(zIn))])
        out = mixer * a
        while out > 10:
            out -= 5
        while out < -10:
            out += 5
        return float(out / 10)