Changeset 8344:3176a3c6e1df in orange


Ignore:
Timestamp:
07/01/11 00:17:13 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
87186325aa999dcda66ebd99d779cab1d8395ec3
Message:

pep8, vertex buffers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/OWGraph3D.py

    r8342 r8344  
     1""" 
     2""" 
     3 
    14from PyQt4.QtCore import * 
    25from PyQt4.QtGui import * 
     
    710from OpenGL.GL import * 
    811from OpenGL.GLU import * 
     12from ctypes import byref, c_char_p, c_int, create_string_buffer 
    913import sys 
    1014import numpy 
    1115from math import sin, cos 
    1216 
     17# Import undefined functions. 
     18try: 
     19  from OpenGL import platform 
     20  gl = platform.OpenGL 
     21except ImportError: 
     22  try: 
     23    gl = cdll.LoadLibrary('libGL.so') 
     24  except OSError: 
     25    from ctypes.util import find_library 
     26    path = find_library('OpenGL') 
     27    gl = cdll.LoadLibrary(path) 
     28 
     29glCreateProgram = gl.glCreateProgram 
     30glCreateShader = gl.glCreateShader 
     31glShaderSource = gl.glShaderSource 
     32glCompileShader = gl.glCompileShader 
     33glGetShaderiv = gl.glGetShaderiv 
     34glDeleteShader = gl.glDeleteShader 
     35 
     36 
    1337def normalize(vec): 
    1438  return vec / numpy.sqrt(numpy.sum(vec** 2)) 
     39 
    1540 
    1641class OWGraph3D(QtOpenGL.QGLWidget): 
     
    2045        self.minx = self.miny = self.minz = 0 
    2146        self.maxx = self.maxy = self.maxz = 0 
    22         self.b_box = [numpy.array([0, 0, 0]), numpy.array([0, 0, 0])] 
    23         self.camera = numpy.array([0.6, 0.8, 0])  # Spherical unit vector around the center. This is where camera is looking from. 
    24         self.center = numpy.array([0, 0, 0])      # Camera is looking into this point. 
    25  
    26         # Try to use displays lists for performance. 
    27         self.sphere_dl = glGenLists(1) # TODO: why does this fail? 
    28         if self.sphere_dl != 0: 
    29           gluQuadric  = gluNewQuadric() 
    30           glNewList(self.sphere_dl, GL_COMPILE) 
    31           gluSphere(gluQuadric, 1, 10, 10) 
    32           glEndList() 
    33           gluDeleteQuadric(gluQuadric) 
    34  
    35         # TODO: other shapes 
     47        self.b_box = [numpy.array([0,   0,   0]), numpy.array([0, 0, 0])] 
     48        self.camera = numpy.array([0.6, 0.8, 0]) # Location on a unit sphere around the center. This is where camera is looking from. 
     49        self.center = numpy.array([0,   0,   0]) 
     50 
    3651        # TODO: move to center shortcut (maybe a GUI element?) 
    3752 
    38         self.yaw = self.pitch = 0 
     53        self.yaw = self.pitch = 0. 
    3954        self.rotation_factor = 100. 
    4055        self.zoom_factor = 100. 
    41         self.zoom = 10 
     56        self.zoom = 10. 
    4257        self.move_factor = 100. 
    43         self.mouse_pos = [100,100] # TODO: get real mouse position, calculate camera, fix the initial jump 
    44         self.updateAxes() 
    45  
    46         self.axisTitleFont = QFont('Helvetica', 10, QFont.Bold) 
    47         self.ticksFont = QFont('Helvetica', 9) 
    48         self.XaxisTitle = '' 
    49         self.YaxisTitle = '' 
    50         self.ZaxisTitle = '' 
     58        self.mouse_pos = [100, 100] # TODO: get real mouse position, calculate camera, fix the initial jump 
     59        self.update_axes() 
     60 
     61        self.axis_title_font = QFont('Helvetica', 10, QFont.Bold) 
     62        self.ticks_font = QFont('Helvetica', 9) 
     63        self.x_axis_title = '' 
     64        self.y_axis_title = '' 
     65        self.z_axis_title = '' 
     66 
     67        self.color_shader = glCreateProgram() 
     68        vertex_shader = glCreateShader(GL_VERTEX_SHADER) 
     69        fragment_shader = glCreateShader(GL_FRAGMENT_SHADER) 
     70 
     71        vertex_shader_source = ''' 
     72            attribute vec4 position; 
     73            attribute vec4 color; 
     74 
     75            uniform mat4 projection; 
     76            uniform mat4 modelview; 
     77 
     78            varying vec4 var_color; 
     79 
     80            void main(void) { 
     81              gl_Position = projection * modelview * position; 
     82              var_color = color; 
     83            } 
     84            ''' 
     85 
     86        fragment_shader_source = ''' 
     87            varying vec4 var_color; 
     88 
     89            void main(void) { 
     90              gl_FragColor = var_color; 
     91            } 
     92            ''' 
     93 
     94        vertex_shader_source = c_char_p(vertex_shader_source) 
     95        fragment_shader_source = c_char_p(fragment_shader_source) 
     96 
     97        def print_log(shader): 
     98          length = c_int() 
     99          glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length)) 
     100 
     101          if length.value > 0: 
     102            log = create_string_buffer(length.value) 
     103            glGetShaderInfoLog(shader, length, byref(length), log) 
     104            print(log.value) 
     105 
     106        length = c_int(-1) 
     107        for shader, source in zip([vertex_shader, fragment_shader], [vertex_shader_source, fragment_shader_source]): 
     108          glShaderSource(shader, 1, byref(source), byref(length)); 
     109          glCompileShader(shader) 
     110          status = c_int() 
     111          glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status)) 
     112          if not status.value: 
     113            print('Failed to compile shader:') 
     114            print_log(shader) 
     115            glDeleteShader(shader) 
     116 
     117        print('Shaders compiled!') 
     118 
    51119 
    52120    def initializeGL(self): 
     
    63131        glLoadIdentity() 
    64132  
    65     def resizeGL(self, w, h): 
    66         glViewport(0, 0, w, h) 
     133 
     134    def resizeGL(self, width, height): 
     135        glViewport(0, 0, width, height) 
    67136        glMatrixMode(GL_PROJECTION) 
    68137        glLoadIdentity() 
    69         if h == 0: 
     138        if height == 0: 
    70139            aspect = 1 
    71140        else: 
    72             aspect = float(w)/float(h) 
     141            aspect = float(width) / height 
    73142        gluPerspective(30.0, aspect, 0.1, 100) 
    74143        glMatrixMode(GL_MODELVIEW) 
    75144        glLoadIdentity() 
     145 
    76146 
    77147    def paintGL(self): 
     
    87157            self.center[2], 
    88158            0, 1, 0) 
    89         self.paintAxes() 
     159        self.paint_axes() 
    90160 
    91161        glEnable(GL_CULL_FACE) 
    92162        glCullFace(GL_BACK) 
    93   
    94         if self.sphere_dl == 0: 
    95           gluQuadric  = gluNewQuadric() 
    96         for cmd, (array, colors, sizes) in self.commands: 
    97             for (x,y,z), (r, g, b, a), size in zip(array, colors, sizes): 
    98                 glPushMatrix() 
    99                 glTranslatef(x, y, z) 
    100                 glColor4f(r, g, b, a) 
    101                 scale = self.normalSize * size 
    102                 glScalef(scale, scale, scale) 
    103                 if self.sphere_dl == 0: 
    104                   gluSphere(gluQuadric, 1, 10, 10) 
    105                 else: 
    106                   glCallList(self.sphere_dl) 
    107                 glPopMatrix() 
    108         if self.sphere_dl == 0: 
    109           gluDeleteQuadric(gluQuadric) 
     163 
     164        for cmd, vertex_buffer in self.commands: 
     165          self.color_shader.bind() 
     166          self.color_shader.setAttributeBuffer(0, GL_FLOAT, 0,   4, 8*4) 
     167          self.color_shader.setAttributeBuffer(1, GL_FLOAT, 4*4, 4, 8*4) 
     168          self.color_shader.enableAttributeArray(0) 
     169          self.color_shader.enableAttributeArray(1) 
     170 
     171          glDrawArrays(GL_TRIANGLES, 0, vertex_buffer.num_vertices); 
     172 
     173          self.color_shader.disableAttributeArray(0) 
     174          self.color_shader.disableAttributeArray(1) 
     175          glUseProgram(0) 
    110176 
    111177        glDisable(GL_CULL_FACE) 
    112178 
    113     def setXaxisTitle(self, title): 
    114       self.XaxisTitle = title 
     179    def set_x_axis_title(self, title): 
     180      self.x_axis_title = title 
    115181      self.updateGL() 
    116182 
    117     def setYaxisTitle(self, title): 
    118       self.YaxisTitle = title 
     183    def set_y_axis_title(self, title): 
     184      self.y_axis_title = title 
    119185      self.updateGL() 
    120186 
    121     def setZaxisTitle(self, title): 
    122       self.ZaxisTitle = title 
     187    def set_z_axis_title(self, title): 
     188      self.z_axis_title = title 
    123189      self.updateGL() 
    124190 
    125     def paintAxes(self): 
     191    def paint_axes(self): 
    126192        glDisable(GL_CULL_FACE) 
    127193        glColor4f(1,1,1,1) 
     
    138204 
    139205        ac = (self.x_axis[0] + self.x_axis[1]) / 2. 
    140         self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.XaxisTitle, font=self.axisTitleFont) 
     206        self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.x_axis_title, font=self.axis_title_font) 
     207 
     208        glPushMatrix(); 
    141209        ac = (self.y_axis[0] + self.y_axis[1]) / 2. 
    142         self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.YaxisTitle, font=self.axisTitleFont) 
     210        glTranslatef(ac[0], ac[1]-0.2, ac[2]-0.2) 
     211        glRotatef(90, 1,0,0); 
     212        #self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.YaxisTitle, font=self.axisTitleFont) 
     213        self.renderText(0,0,0, self.y_axis_title, font=self.axis_title_font) 
     214        glPopMatrix(); 
     215 
    143216        ac = (self.z_axis[0] + self.z_axis[1]) / 2. 
    144         self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.ZaxisTitle, font=self.axisTitleFont) 
     217        self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.z_axis_title, font=self.axis_title_font) 
    145218 
    146219        outwards = normalize(self.x_axis[0] - bb_center) 
     
    150223        glColor4f(1,1,1,1) 
    151224 
    152         def paintGrid(planeQuad, sub=20): 
    153             P11, P12, P22, P21 = numpy.asarray(planeQuad) 
     225        def paint_grid(plane_quad, sub=20): 
     226            P11, P12, P22, P21 = numpy.asarray(plane_quad) 
    154227            Dx = numpy.linspace(0.0, 1.0, num=sub) 
    155228            P1vecH = P12 - P11 
     
    170243            glEnd() 
    171244 
    172         def paintQuad(planeQuad): 
    173             P11, P12, P21, P22 = numpy.asarray(planeQuad) 
     245        def paint_quad(plane_quad): 
     246            P11, P12, P21, P22 = numpy.asarray(plane_quad) 
    174247            glBegin(GL_QUADS) 
    175248            glVertex3f(*P11) 
     
    179252            glEnd() 
    180253 
    181         colorPlane = [0.5, 0.5, 0.5, 0.5] 
    182         colorGrid = [0.3, 0.3, 0.3, 1.0] 
    183  
    184         def paintPlain(planeQuad): 
     254        color_plane = [0.5, 0.5, 0.5, 0.5] 
     255        color_grid = [0.3, 0.3, 0.3, 1.0] 
     256 
     257        def paint_plane(plane_quad): 
    185258            #glColor4f(*colorPlane) 
    186259            #paintQuad(planeQuad) 
    187             glColor4f(*colorGrid) 
    188             paintGrid(planeQuad) 
    189  
    190         def normalFromPoints(P1, P2, P3): 
     260            glColor4f(*color_grid) 
     261            paint_grid(plane_quad) 
     262 
     263        def normal_from_points(P1, P2, P3): 
    191264            V1 = P2 - P1 
    192265            V2 = P3 - P1 
    193266            return normalize(numpy.cross(V1, V2)) 
    194267  
    195         def drawGridVisible(planeQuad, ccw=False): 
    196             normal = normalFromPoints(*planeQuad[:3]) 
    197             camInSpace = numpy.array([ 
     268        def draw_grid_visible(plane_quad, ccw=False): 
     269            normal = normal_from_points(*plane_quad[:3]) 
     270            cam_in_space = numpy.array([ 
    198271              self.center[0] + self.camera[0]*self.zoom, 
    199272              self.center[1] + self.camera[1]*self.zoom, 
    200273              self.center[2] + self.camera[2]*self.zoom 
    201274            ]) 
    202             cameraVector = normalize(planeQuad[0] - camInSpace) 
    203             cos = numpy.dot(normal, cameraVector) * (-1 if ccw else 1) 
     275            camera_vector = normalize(plane_quad[0] - cam_in_space) 
     276            cos = numpy.dot(normal, camera_vector) * (-1 if ccw else 1) 
    204277            if cos > 0: 
    205                 paintPlain(planeQuad) 
    206  
    207         drawGridVisible(self.axisPlaneXY) 
    208         drawGridVisible(self.axisPlaneYZ) 
    209         drawGridVisible(self.axisPlaneXZ) 
    210         drawGridVisible(self.axisPlaneXYBack) 
    211         drawGridVisible(self.axisPlaneYZRight) 
    212         drawGridVisible(self.axisPLaneXZTop) 
     278                paint_plane(plane_quad) 
     279 
     280        draw_grid_visible(self.axis_plane_xy) 
     281        draw_grid_visible(self.axis_plane_yz) 
     282        draw_grid_visible(self.axis_plane_xz) 
     283        draw_grid_visible(self.axis_plane_xy_back) 
     284        draw_grid_visible(self.axis_plane_yz_right) 
     285        draw_grid_visible(self.axis_plane_xz_top) 
    213286 
    214287        glEnable(GL_CULL_FACE) 
    215288 
    216     def updateAxes(self): 
     289    def update_axes(self): 
    217290        x_axis = [[self.minx, self.miny, self.minz], 
    218291                  [self.maxx, self.miny, self.minz]] 
     
    239312        H = D + unit_z 
    240313 
    241         self.axisPlaneXY = [A, B, C, D] 
    242         self.axisPlaneYZ = [A, D, H, E] 
    243         self.axisPlaneXZ = [D, C, G, H] 
    244  
    245         self.axisPlaneXYBack = [H, G, F, E] 
    246         self.axisPlaneYZRight = [B, F, G, C] 
    247         self.axisPLaneXZTop = [E, F, B, A] 
    248  
    249     def scatter(self, X, Y, Z=0, c="b", s=20, **kwargs): 
     314        self.axis_plane_xy = [A, B, C, D] 
     315        self.axis_plane_yz = [A, D, H, E] 
     316        self.axis_plane_xz = [D, C, G, H] 
     317 
     318        self.axis_plane_xy_back = [H, G, F, E] 
     319        self.axis_plane_yz_right = [B, F, G, C] 
     320        self.axis_plane_xz_top = [E, F, B, A] 
     321 
     322    def scatter(self, X, Y, Z, c="b", s=20, **kwargs): 
    250323        array = [[x, y, z] for x,y,z in zip(X, Y, Z)] 
    251324        if isinstance(c, str): 
    252             colorDict ={"r": [1.0, 0.0, 0.0, 1.0], 
    253                         "g": [0.0, 1.0, 0.0, 1.0], 
    254                         "b": [0.0, 0.0, 1.0, 1.0]} 
     325            color_map = {"r": [1.0, 0.0, 0.0, 1.0], 
     326                         "g": [0.0, 1.0, 0.0, 1.0], 
     327                         "b": [0.0, 0.0, 1.0, 1.0]} 
    255328            default = [0.0, 0.0, 1.0, 1.0] 
    256             colors = [colorDict.get(c, default) for i in array] 
     329            colors = [color_map.get(c, default) for _ in array] 
    257330        else: 
    258331            colors = c 
     
    261334            s = [s for _ in array] 
    262335 
    263         self.commands.append(("scatter", (array, colors, s))) 
    264336        max, min = numpy.max(array, axis=0), numpy.min(array, axis=0) 
    265337        self.b_box = [max, min] 
     
    267339        self.maxx, self.maxy, self.maxz = max 
    268340        self.center = (min + max) / 2  
    269         self.normalSize = numpy.max(self.center - self.b_box[1]) / 100. 
    270         self.updateAxes() 
     341        self.normal_size = numpy.max(self.center - self.b_box[1]) / 100. 
     342 
     343        vertex_buffer = QtOpenGL.QGLBuffer(QtOpenGL.QGLBuffer.VertexBuffer) 
     344        if vertex_buffer.create() == False: 
     345          print('Warning: vertex buffers not supported') 
     346          return 
     347 
     348        vertex_buffer.bind() 
     349        vertex_buffer.setUsagePattern(QtOpenGL.QGLBuffer.StaticDraw) 
     350 
     351        vertices = [] 
     352        for (x,y,z), (r,g,b,a), size in zip(array, colors, s): 
     353          vertices.extend([x-size*self.normal_size,y,z, r,g,b,a]) 
     354          vertices.extend([x+size*self.normal_size,y,z, r,g,b,a]) 
     355          vertices.extend([x,y+size*self.normal_size,z, r,g,b,a]) 
     356 
     357        vertex_buffer.allocate((GLfloat * len(vertices))(vertices), len(vertices)*4) 
     358 
     359        self.commands.append(("scatter", (vertex_buffer))) 
     360        self.update_axes() 
    271361        self.updateGL() 
    272362  
     
    296386    def wheelEvent(self, event): 
    297387      if event.orientation() == Qt.Vertical: 
    298         self.zoom += event.delta() / self.zoom_factor 
     388        self.zoom -= event.delta() / self.zoom_factor 
    299389        if self.zoom < 2: 
    300390          self.zoom = 2 
     
    310400  
    311401    from random import random 
    312     rand = lambda :random() - 0.5 
     402    rand = lambda: random() - 0.5 
    313403    N = 100 
    314404    data = orange.ExampleTable("../doc/datasets/iris.tab") 
Note: See TracChangeset for help on using the changeset viewer.