Changeset 8731:1b62d1db5d3c in orange


Ignore:
Timestamp:
08/19/11 15:28:03 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
384045ab6a941e76229f3d744617e431cb6817e5
Message:

Work on radviz3d: cones represent anchors; closest neighbour spherical grid

Location:
orange/OrangeWidgets
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/Visualize Qt/OWRadviz3D.py

    r8729 r8731  
    66 
    77import os 
     8from math import acos, atan2, pi 
    89 
    910from plot.owplot3d import * 
     
    3738    def setData(self, data, subsetData=None, **args): 
    3839        orngScaleLinProjData3D.setData(self, data, subsetData, **args) 
    39         OWPlot3D.set_data(self, self.no_jittering_scaled_data, self.no_jittering_scaled_subset_data) 
     40        self.initializeGL() # Apparently this is not called already 
     41        self.makeCurrent() 
     42        #OWPlot3D.set_data(self, self.no_jittering_scaled_data, self.no_jittering_scaled_subset_data) 
     43 
     44        if hasattr(self, 'sphere_vao_id'): 
     45            return 
    4046 
    4147        sphere_data = parse_obj(os.path.join(os.path.dirname(__file__), '../plot/primitives/sphere_hq.obj')) 
     
    6571        self.sphere_vao_id.num_vertices = len(vertices) / (vertex_size / 4) 
    6672 
     73        cone_data = parse_obj(os.path.join(os.path.dirname(__file__), '../plot/primitives/cone_hq.obj')) 
     74        vertices = [] 
     75        for v0, v1, v2, n0, n1, n2 in cone_data: 
     76            vertices.extend([v0[0],v0[1],v0[2], n0[0],n0[1],n0[2], 
     77                             v1[0],v1[1],v1[2], n1[0],n1[1],n1[2], 
     78                             v2[0],v2[1],v2[2], n2[0],n2[1],n2[2]]) 
     79 
     80        self.cone_vao_id = GLuint(0) 
     81        glGenVertexArrays(1, self.cone_vao_id) 
     82        glBindVertexArray(self.cone_vao_id) 
     83 
     84        vertex_buffer_id = glGenBuffers(1) 
     85        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id) 
     86        glBufferData(GL_ARRAY_BUFFER, numpy.array(vertices, 'f'), GL_STATIC_DRAW) 
     87 
     88        vertex_size = (3+3)*4 
     89        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(0)) 
     90        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(3*4)) 
     91        glEnableVertexAttribArray(0) 
     92        glEnableVertexAttribArray(1) 
     93 
     94        glBindVertexArray(0) 
     95        glBindBuffer(GL_ARRAY_BUFFER, 0) 
     96 
     97        self.cone_vao_id.num_vertices = len(vertices) / (vertex_size / 4) 
     98 
     99        # Geometry shader-based wireframe rendering 
     100        # (http://cgg-journal.com/2008-2/06/index.html) 
    67101        self.sphere_shader = QtOpenGL.QGLShaderProgram() 
    68         vertex_shader_source = ''' 
    69             #extension GL_EXT_gpu_shader4 : enable 
    70  
     102        geometry_shader_source = '''#version 150 
     103            layout(triangles) in; 
     104            layout(triangle_strip, max_vertices=3) out; 
     105 
     106            uniform mat4 projection; 
     107            uniform mat4 modelview; 
     108            uniform vec3 cam_position; 
     109            out float transparency; 
     110 
     111            uniform vec2 win_scale; 
     112            noperspective out vec3 dist; 
     113 
     114            void main(void) 
     115            { 
     116                vec4 pos_in0 = projection * modelview * gl_PositionIn[0]; 
     117                vec4 pos_in1 = projection * modelview * gl_PositionIn[1]; 
     118                vec4 pos_in2 = projection * modelview * gl_PositionIn[2]; 
     119                vec2 p0 = win_scale * pos_in0.xy / pos_in0.w; 
     120                vec2 p1 = win_scale * pos_in1.xy / pos_in1.w; 
     121                vec2 p2 = win_scale * pos_in2.xy / pos_in2.w; 
     122 
     123                vec2 v0 = p2-p1; 
     124                vec2 v1 = p2-p0; 
     125                vec2 v2 = p1-p0; 
     126                float area = abs(v1.x*v2.y - v1.y * v2.x); 
     127 
     128                dist = vec3(area / length(v0), 0., 0.); 
     129                gl_Position = pos_in0; 
     130                transparency = clamp(dot(normalize(cam_position-gl_PositionIn[0].xyz), normalize(gl_PositionIn[0].xyz)), 0., 1.); 
     131                EmitVertex(); 
     132 
     133                dist = vec3(0., area / length(v1), 0.); 
     134                gl_Position = pos_in1; 
     135                transparency = clamp(dot(normalize(cam_position-gl_PositionIn[1].xyz), normalize(gl_PositionIn[1].xyz)), 0., 1.); 
     136                EmitVertex(); 
     137 
     138                dist = vec3(0., 0., area / length(v2)); 
     139                gl_Position = pos_in2; 
     140                transparency = clamp(dot(normalize(cam_position-gl_PositionIn[2].xyz), normalize(gl_PositionIn[2].xyz)), 0., 1.); 
     141                EmitVertex(); 
     142 
     143                EndPrimitive(); 
     144            } 
     145        ''' 
     146 
     147        vertex_shader_source = '''#version 150 
    71148            attribute vec3 position; 
    72149            attribute vec3 normal; 
    73150 
    74             uniform vec3 color; 
    75  
    76             varying vec4 var_color; 
    77  
    78             void main(void) { 
    79                 gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(position*8.6602, 1.); 
    80                 var_color = vec4(0.8, 0.8, 0.8, 0.2); 
     151            void main(void) 
     152            { 
     153                gl_Position = vec4(position, 1.); 
    81154            } 
    82155            ''' 
    83156 
    84         fragment_shader_source = ''' 
    85             varying vec4 var_color; 
    86  
    87             void main(void) { 
    88               gl_FragColor = var_color; 
     157        fragment_shader_source = '''#version 150 
     158            in float transparency; 
     159            noperspective in vec3 dist; 
     160 
     161            const vec4 wire_color = vec4(0.5, 0.5, 0.5, 0.5); 
     162            const vec4 fill_color = vec4(1., 1., 1., 0.5); 
     163 
     164            void main(void) 
     165            { 
     166                float d = min(dist[0], min(dist[1], dist[2])); 
     167                gl_FragColor = mix(wire_color, fill_color, 1. - exp2(-1*d*d)); 
     168                gl_FragColor.a = 1. - transparency - 0.6; 
    89169            } 
    90170            ''' 
    91171 
     172        self.sphere_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Geometry, geometry_shader_source) 
    92173        self.sphere_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Vertex, vertex_shader_source) 
    93174        self.sphere_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Fragment, fragment_shader_source) 
     
    98179        if not self.sphere_shader.link(): 
    99180            print('Failed to link sphere shader!') 
    100         else: 
    101             print('Sphere shader linked.') 
     181 
     182        vertex_shader_source = '''#version 150 
     183            in vec3 position; 
     184            in vec3 normal; 
     185 
     186            out vec4 color; 
     187 
     188            uniform mat4 projection; 
     189            uniform mat4 modelview; 
     190 
     191            const vec3 light_direction = normalize(vec3(-0.7, 0.42, 0.21)); 
     192 
     193            void main(void) 
     194            { 
     195                gl_Position = projection * modelview * vec4(position, 1.); 
     196                float diffuse = clamp(dot(light_direction, normalize((modelview * vec4(normal, 0.)).xyz)), 0., 1.); 
     197                color = vec4(vec3(0., 1., 0.) * diffuse, 1.); 
     198            } 
     199            ''' 
     200        fragment_shader_source = '''#version 150 
     201            in vec4 color; 
     202 
     203            void main(void) 
     204            { 
     205                gl_FragColor = color; 
     206            } 
     207            ''' 
     208 
     209        self.cone_shader = QtOpenGL.QGLShaderProgram() 
     210        self.cone_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Vertex, vertex_shader_source) 
     211        self.cone_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Fragment, fragment_shader_source) 
     212 
     213        self.cone_shader.bindAttributeLocation('position', 0) 
     214        self.cone_shader.bindAttributeLocation('normal', 1) 
     215 
     216        if not self.cone_shader.link(): 
     217            print('Failed to link cone shader!') 
    102218 
    103219    def updateData(self, labels=None, setAnchors=0, **args): 
    104         print('updateData') 
    105220        self.clear() 
    106221 
    107         #if not self.have_data or len(labels) < 3: 
    108             #self.anchor_data = [] 
     222        if not self.have_data or len(labels) < 3: 
     223            self.anchor_data = [] 
    109224            #self.updateLayout() 
    110             #return 
    111  
    112         #if setAnchors: 
    113             #self.setAnchors(args.get('XAnchors'), args.get('YAnchors'), args.get('ZAnchors'), labels) 
    114  
    115         #data_size = len(self.rawData) 
    116         #indices = [self.attributeNameIndex[anchor[3]] for anchor in self.anchor_data] 
    117         #valid_data = self.getValidList(indices) 
    118         #trans_proj_data = self.createProjectionAsNumericArray(indices, validData=valid_data, 
    119             #scaleFactor=self.scaleFactor, normalize=self.normalizeExamples, jitterSize=-1, 
    120             #useAnchorData=1, removeMissingData=0) 
    121         #if trans_proj_data == None: 
    122             #return 
     225            return 
     226 
     227        if setAnchors: 
     228            self.setAnchors(args.get('XAnchors'), args.get('YAnchors'), args.get('ZAnchors'), labels) 
     229 
     230        data_size = len(self.rawData) 
     231        indices = [self.attributeNameIndex[anchor[3]] for anchor in self.anchor_data] 
     232        valid_data = self.getValidList(indices) 
     233        trans_proj_data = self.createProjectionAsNumericArray(indices, validData=valid_data, 
     234            scaleFactor=self.scaleFactor, normalize=self.normalizeExamples, jitterSize=-1, 
     235            useAnchorData=1, removeMissingData=0) 
     236        if trans_proj_data == None: 
     237            return 
     238         
     239        self.set_data(trans_proj_data, None) 
     240        self.set_shown_attributes_indices(0, 1, 2, -1, -1, -1, -1, [], -1, 
     241                                          False, False, False, 
     242                                          self.jitter_size, self.jitter_continuous, 
     243                                          numpy.array([1., 1., 1.]), numpy.array([0., 0., 0.])) 
    123244        #proj_data = trans_proj_data.T 
    124245        #x_positions = proj_data[0] 
     
    128249        #self.scatter(x_positions, y_positions, z_positions) 
    129250 
     251        def before_draw_callback(): 
     252            # Override modelview (scatterplot points camera somewhat below the center, which doesn't 
     253            # look good with radviz sphere) 
     254            modelview = QMatrix4x4() 
     255            modelview.lookAt( 
     256                QVector3D(self.camera[0]*self.camera_distance, 
     257                          self.camera[1]*self.camera_distance, 
     258                          self.camera[2]*self.camera_distance), 
     259                QVector3D(0, 0, 0), 
     260                QVector3D(0, 1, 0)) 
     261            self.modelview = modelview 
     262 
     263        self.before_draw_callback = before_draw_callback 
    130264        self.after_draw_callback = self.draw_sphere_callback 
    131265        self.updateGL() 
    132266 
    133267    def updateGraph(self, attrList=None, setAnchors=0, insideColors=None, **args): 
    134         pass 
     268        print('updateGraph') 
    135269 
    136270    def draw_sphere_callback(self): 
     
    140274 
    141275        self.sphere_shader.bind() 
     276        self.sphere_shader.setUniformValue('win_scale', self.width(), self.height()) 
     277        self.sphere_shader.setUniformValue('projection', self.projection) 
     278        self.sphere_shader.setUniformValue('modelview', self.modelview) 
     279        self.sphere_shader.setUniformValue('cam_position', QVector3D(*self.camera)*self.camera_distance) 
    142280        glBindVertexArray(self.sphere_vao_id) 
    143281 
    144         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) 
     282        glEnable(GL_CULL_FACE) 
     283        glCullFace(GL_FRONT) 
    145284        glDrawArrays(GL_TRIANGLES, 0, self.sphere_vao_id.num_vertices) 
    146         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) 
     285        glCullFace(GL_BACK) 
     286        glDrawArrays(GL_TRIANGLES, 0, self.sphere_vao_id.num_vertices) 
     287        glDisable(GL_CULL_FACE) 
    147288 
    148289        glBindVertexArray(0) 
    149290        self.sphere_shader.release() 
    150291 
    151         radius = (25*3)**0.5 
     292        glMatrixMode(GL_PROJECTION) 
     293        glLoadIdentity() 
     294        glMultMatrixd(numpy.array(self.projection.data(), dtype=float)) 
     295        glMatrixMode(GL_MODELVIEW) 
     296        glLoadIdentity() 
     297        glMultMatrixd(numpy.array(self.modelview.data(), dtype=float)) 
     298 
     299        # Two more ways to visualize sphere: 
     300        #glColor3f(0., 0., 0.) 
     301        #glDisable(GL_BLEND) 
     302        #num_rings = 24 
     303        #num_parts = 30 
     304        #r = 1. 
     305        #glBegin(GL_LINES) 
     306        #for i in range(num_rings): 
     307            #z_offset = float(i) * 2 / num_rings - 1. 
     308            #r = (1. - z_offset**2)**0.5 
     309            #for j in range(num_parts): 
     310                #angle_z_0 = float(j) * 2 * pi / num_parts 
     311                #angle_z_1 = float(j+1) * 2 * pi / num_parts 
     312                #glVertex3f(sin(angle_z_0)*r, cos(angle_z_0)*r, z_offset) 
     313                #glVertex3f(sin(angle_z_1)*r, cos(angle_z_1)*r, z_offset) 
     314            #for j in range(num_parts): 
     315                #angle_z_0 = float(j) * 2 * pi / num_parts 
     316                #angle_z_1 = float(j+1) * 2 * pi / num_parts 
     317                #glVertex3f(sin(angle_z_0)*r, z_offset, cos(angle_z_0)*r) 
     318                #glVertex3f(sin(angle_z_1)*r, z_offset, cos(angle_z_1)*r) 
     319        #glEnd() 
     320 
     321        #for i in range(num_rings): 
     322            #angle_y = float(i) * 2 * pi / num_rings 
     323            #glBegin(GL_LINES) 
     324            #for j in range(num_parts): 
     325                #angle_x_0 = float(j) * 2 * pi / num_parts 
     326                #angle_x_1 = float(j+1) * 2 * pi / num_parts 
     327                #glVertex3f(r * sin(angle_x_0) * cos(angle_y), 
     328                           #r * cos(angle_x_0), 
     329                           #r * sin(angle_x_0) * sin(angle_y)) 
     330                #glVertex3f(r * sin(angle_x_1) * cos(angle_y), 
     331                           #r * cos(angle_x_1), 
     332                           #r * sin(angle_x_1) * sin(angle_y)) 
     333            #glEnd() 
     334 
     335        glEnable(GL_DEPTH_TEST) 
     336        glDisable(GL_BLEND) 
     337        radius = 1. 
    152338 
    153339        if self.showAnchors: 
    154340            for anchor in self.anchor_data: 
    155341                x, y, z, label = anchor 
    156                 glLineWidth(2.) 
    157                 glColor4f(0.8, 0, 0, 1) 
    158                 glBegin(GL_LINES) 
    159                 glVertex3f(x*0.98*radius, y*0.99*radius, z*0.98*radius) 
    160                 glVertex3f(x*1.02*radius, y*1.02*radius, z*1.02*radius) 
    161                 glEnd() 
    162                 glLineWidth(1.) 
     342 
     343                direction = QVector3D(x, y, z) 
     344                up = QVector3D(0, 1, 0) 
     345                right = QVector3D.crossProduct(direction, up).normalized() 
     346                up = QVector3D.crossProduct(right, direction) 
     347                rotation = QMatrix4x4() 
     348                rotation.setColumn(0, QVector4D(right, 0)) 
     349                rotation.setColumn(1, QVector4D(up, 0)) 
     350                rotation.setColumn(2, QVector4D(direction, 0)) 
     351 
     352                self.cone_shader.bind() 
     353                self.cone_shader.setUniformValue('projection', self.projection) 
     354                modelview = QMatrix4x4(self.modelview) 
     355                modelview.translate(x, y, z) 
     356                modelview = modelview * rotation 
     357                modelview.rotate(-90, 1, 0, 0) 
     358                modelview.translate(0, -0.03, 0) 
     359                modelview.scale(-0.03, -0.03, -0.03) 
     360                self.cone_shader.setUniformValue('modelview', modelview) 
     361 
     362                glBindVertexArray(self.cone_vao_id) 
     363                glDrawArrays(GL_TRIANGLES, 0, self.cone_vao_id.num_vertices) 
     364                glBindVertexArray(0) 
     365 
     366                self.cone_shader.release() 
    163367 
    164368                glColor4f(0, 0, 0, 1) 
    165                 self.renderText(x*1.1*radius, y*1.1*radius, z*1.1*radius, label) 
     369                self.renderText(x*1.3*radius, y*1.3*radius, z*1.3*radius, label) 
     370 
     371            num_parts = 30 
     372            anchors = array([a[:3] for a in self.anchor_data]) 
     373            for anchor in self.anchor_data: 
     374                a0 = array(anchor[:3]) 
     375                neighbours = anchors.copy() 
     376                neighbours = [(((n-a0)**2).sum(), n)  for n in neighbours] 
     377                neighbours.sort(key=lambda e: e[0]) 
     378                for i in range(1, min(len(anchors), 4)):  
     379                    difference = neighbours[i][1]-a0 
     380                    glBegin(GL_LINES) 
     381                    for j in range(num_parts): 
     382                        glVertex3f(*normalize(a0 + difference*j/float(num_parts))) 
     383                        glVertex3f(*normalize(a0 + difference*(j+1)/float(num_parts))) 
     384                    glEnd(GL_LINES) 
    166385 
    167386    def setCanvasColor(self, c): 
  • orange/OrangeWidgets/plot/generator.gs

    r8730 r8731  
    1313uniform bool use_2d_symbols; 
    1414 
    15 uniform float seed; 
    1615uniform float jitter_size; 
    1716uniform bool jitter_continuous; 
  • orange/OrangeWidgets/plot/owplot3d.py

    r8730 r8731  
    402402 
    403403        self.build_axes() 
     404         
     405        self.data = None 
    404406 
    405407    def __del__(self): 
     
    412414 
    413415    def initializeGL(self): 
     416        if hasattr(self, 'generating_program'): 
     417            return 
     418        self.makeCurrent() 
    414419        glClearColor(1.0, 1.0, 1.0, 1.0) 
    415420        glClearDepth(1.0) 
     
    591596 
    592597    def paintGL(self): 
    593         if not self.feedback_generated: 
    594             return 
    595  
    596598        glViewport(0, 0, self.width(), self.height()) 
    597599        glClearColor(*self._theme.background_color) 
    598600        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
     601 
     602        if not self.feedback_generated: 
     603            return 
    599604 
    600605        modelview, projection = self.get_mvp() 
     
    946951        self.generating_program.setUniformValue('y_index', y_index) 
    947952        self.generating_program.setUniformValue('z_index', z_index) 
    948         self.generating_program.setUniformValue('seed', time.time()) 
    949953        self.generating_program.setUniformValue('jitter_size', jitter_size) 
    950954        self.generating_program.setUniformValue('jitter_continuous', jitter_continuous) 
     
    9981002    def set_data(self, data, subset_data=None): 
    9991003        self.makeCurrent() 
     1004        #if self.data != None: 
     1005            #TODO: glDeleteBuffers(1, self.data_buffer) 
    10001006        start = time.time() 
    10011007 
Note: See TracChangeset for help on using the changeset viewer.