Changeset 8349:f2c07c81337c in orange


Ignore:
Timestamp:
07/04/11 20:06:07 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
127655484ffdab111c704f25f51f20962efce9d9
Message:

Axes values, highlight

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orange/OrangeWidgets/OWGraph3D.py

    r8345 r8349  
    1818# Import undefined functions, override some wrappers. 
    1919try: 
    20   from OpenGL import platform 
    21   gl = platform.OpenGL 
     20    from OpenGL import platform 
     21    gl = platform.OpenGL 
    2222except ImportError: 
    23   try: 
    24     gl = cdll.LoadLibrary('libGL.so') 
    25   except OSError: 
    26     from ctypes.util import find_library 
    27     path = find_library('OpenGL') 
    28     gl = cdll.LoadLibrary(path) 
     23    try: 
     24        gl = cdll.LoadLibrary('libGL.so') 
     25    except OSError: 
     26        from ctypes.util import find_library 
     27        path = find_library('OpenGL') 
     28        gl = cdll.LoadLibrary(path) 
    2929 
    3030glCreateProgram = gl.glCreateProgram 
     
    4444glVertexAttribPointer = gl.glVertexAttribPointer 
    4545glEnableVertexAttribArray = gl.glEnableVertexAttribArray 
    46 #glBegin = gl.glBegin 
    47 #glEnd = gl.glEnd 
    48 #glColor4f = gl.glColor4f 
    49 #glColor3f = gl.glColor3f 
    5046 
    5147 
    5248def normalize(vec): 
    53   return vec / numpy.sqrt(numpy.sum(vec** 2)) 
     49    return vec / numpy.sqrt(numpy.sum(vec** 2)) 
    5450 
    5551 
     
    7369        self.move_factor = 100. 
    7470        self.mouse_pos = [100, 100] # TODO: get real mouse position, calculate camera, fix the initial jump 
    75         #self.update_axes() 
    7671 
    7772        self.axis_title_font = QFont('Helvetica', 10, QFont.Bold) 
     
    8176        self.z_axis_title = '' 
    8277 
     78        self.color_plane = numpy.array([0.95, 0.95, 0.95, 0.3]) 
     79        self.color_grid = numpy.array([0.8, 0.8, 0.8, 1.0]) 
     80 
    8381        self.vertex_buffers = [] 
    8482        self.vaos = [] 
    8583 
    8684    def __del__(self): 
    87       #for shader in self.shaders: 
    88       #  glDeleteShader(shader) 
    89  
    90       glDeleteProgram(self.color_shader) 
    91  
    92       #for vertex_buffer in self.vertex_buffers: 
    93       #  glDeleteBuffers(1, byref(vertex_buffer)) 
     85        glDeleteProgram(self.color_shader) 
    9486 
    9587    def initializeGL(self): 
     
    9991        glDepthFunc(GL_LESS) 
    10092        glEnable(GL_DEPTH_TEST) 
    101         glShadeModel(GL_SMOOTH) 
    102         #glEnable(GL_BLEND) 
    103         #glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
     93        glEnable(GL_LINE_SMOOTH) 
    10494 
    10595        self.color_shader = glCreateProgram() 
     
    156146 
    157147        def print_log(shader): 
    158           length = c_int() 
    159           glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length)) 
    160  
    161           if length.value > 0: 
    162             log = create_string_buffer(length.value) 
    163             glGetShaderInfoLog(shader, length, byref(length), log) 
    164             print(log.value) 
     148            length = c_int() 
     149            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, byref(length)) 
     150 
     151            if length.value > 0: 
     152                log = create_string_buffer(length.value) 
     153                glGetShaderInfoLog(shader, length, byref(length), log) 
     154                print(log.value) 
    165155 
    166156        length = c_int(-1) 
    167157        for shader, source in zip([vertex_shader, fragment_shader], 
    168158                                  [vertex_shader_source, fragment_shader_source]): 
    169           glShaderSource(shader, 1, byref(source), byref(length)) 
    170           glCompileShader(shader) 
    171           status = c_int() 
    172           glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status)) 
    173           if not status.value: 
    174             print_log(shader) 
    175             glDeleteShader(shader) 
    176             return 
    177           else: 
    178             glAttachShader(self.color_shader, shader) 
     159            glShaderSource(shader, 1, byref(source), byref(length)) 
     160            glCompileShader(shader) 
     161            status = c_int() 
     162            glGetShaderiv(shader, GL_COMPILE_STATUS, byref(status)) 
     163            if not status.value: 
     164                print_log(shader) 
     165                glDeleteShader(shader) 
     166                return 
     167            else: 
     168                glAttachShader(self.color_shader, shader) 
    179169 
    180170        glBindAttribLocation(self.color_shader, 0, 'position') 
     
    196186        aspect = float(self.width()) / self.height() if self.height() != 0 else 1 
    197187        gluPerspective(30.0, aspect, 0.1, 100) 
    198         glMatrixMode(GL_MODELVIEW) 
    199         glLoadIdentity() 
    200188        glMatrixMode(GL_MODELVIEW) 
    201189        glLoadIdentity() 
     
    210198        self.paint_axes() 
    211199 
     200        glEnable(GL_DEPTH_TEST) 
    212201        glDisable(GL_CULL_FACE) 
    213202 
    214203        for cmd, vao in self.commands: 
    215           if cmd == 'scatter': 
    216             glUseProgram(self.color_shader) 
    217             glBindVertexArray(vao.value) 
    218             glDrawArrays(GL_TRIANGLES, 0, vao.num_vertices) 
    219             glBindVertexArray(0) 
    220             glUseProgram(0) 
     204            if cmd == 'scatter': 
     205                glUseProgram(self.color_shader) 
     206                glBindVertexArray(vao.value) 
     207                glDrawArrays(GL_TRIANGLES, 0, vao.num_vertices) 
     208                glBindVertexArray(0) 
     209                glUseProgram(0) 
    221210 
    222211    def set_x_axis_title(self, title): 
    223       self.x_axis_title = title 
    224       self.updateGL() 
     212        self.x_axis_title = title 
     213        self.updateGL() 
    225214 
    226215    def set_y_axis_title(self, title): 
    227       self.y_axis_title = title 
    228       self.updateGL() 
     216        self.y_axis_title = title 
     217        self.updateGL() 
    229218 
    230219    def set_z_axis_title(self, title): 
    231       self.z_axis_title = title 
    232       self.updateGL() 
     220        self.z_axis_title = title 
     221        self.updateGL() 
    233222 
    234223    def paint_axes(self): 
    235         glDisable(GL_CULL_FACE) 
    236         glColor4f(1,1,1,1) 
    237         for start, end in [self.x_axis, self.y_axis, self.z_axis]: 
     224        cam_in_space = numpy.array([ 
     225          self.center[0] + self.camera[0]*self.zoom, 
     226          self.center[1] + self.camera[1]*self.zoom, 
     227          self.center[2] + self.camera[2]*self.zoom 
     228        ]) 
     229 
     230        def normal_from_points(p1, p2, p3): 
     231            v1 = p2 - p1 
     232            v2 = p3 - p1 
     233            return normalize(numpy.cross(v1, v2)) 
     234 
     235        def plane_visible(plane): 
     236            normal = normal_from_points(*plane[:3]) 
     237            cam_plane = normalize(plane[0] - cam_in_space) 
     238            if numpy.dot(normal, cam_plane) > 0: 
     239                return False 
     240            return True 
     241 
     242        def draw_line(line): 
     243            glColor4f(0.2, 0.2, 0.2, 1) 
     244            glLineWidth(2) # Widths > 1 are actually deprecated I think. 
    238245            glBegin(GL_LINES) 
    239             glVertex3f(*start) 
    240             glVertex3f(*end) 
     246            glVertex3f(*line[0]) 
     247            glVertex3f(*line[1]) 
    241248            glEnd() 
    242249 
     250        def draw_values(axis, coord_index, normal, sub=10): 
     251            glColor4f(0.1, 0.1, 0.1, 1) 
     252            glLineWidth(1) 
     253            start = axis[0] 
     254            end = axis[1] 
     255            direction = (end - start) / float(sub) 
     256            middle = (end - start) / 2. 
     257            offset = normal*0.3 
     258            for i in range(sub): 
     259                position = start + direction*i 
     260                glBegin(GL_LINES) 
     261                glVertex3f(*(position-normal*0.08)) 
     262                glVertex3f(*(position+normal*0.08)) 
     263                glEnd() 
     264                position += offset 
     265                self.renderText(position[0], 
     266                                position[1], 
     267                                position[2], 
     268                                '{0:.2}'.format(position[coord_index])) 
     269 
     270        glDisable(GL_DEPTH_TEST) 
     271        glLineWidth(1) 
     272        glEnable(GL_BLEND) 
     273        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    243274        bb_center = (self.b_box[1] + self.b_box[0]) / 2. 
    244275 
    245276        # Draw axis labels. 
    246277        glColor4f(0,0,0,1) 
    247  
    248         ac = (self.x_axis[0] + self.x_axis[1]) / 2. 
    249         self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.x_axis_title, font=self.axis_title_font) 
    250  
    251         glPushMatrix() 
    252         ac = (self.y_axis[0] + self.y_axis[1]) / 2. 
    253         glTranslatef(ac[0], ac[1]-0.2, ac[2]-0.2) 
    254         glRotatef(90, 1,0,0) 
    255         #self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.YaxisTitle, font=self.axisTitleFont) 
    256         self.renderText(0,0,0, self.y_axis_title, font=self.axis_title_font) 
    257         glPopMatrix() 
    258  
    259         ac = (self.z_axis[0] + self.z_axis[1]) / 2. 
    260         self.renderText(ac[0], ac[1]-0.2, ac[2]-0.2, self.z_axis_title, font=self.axis_title_font) 
    261  
    262         glEnable(GL_TEXTURE_2D) 
    263         glBindTexture(GL_TEXTURE_2D, self.x_axis_frame.texture()) 
    264  
    265         glBegin(GL_QUADS) 
    266         glTexCoord2f(0,1) 
    267         glVertex3f(*self.x_axis[0]) 
    268         glTexCoord2f(1,1) 
    269         glVertex3f(*self.x_axis[1]) 
    270         glTexCoord2f(1,0) 
    271         glVertex3f(*(self.x_axis[1] + [0,0,-0.5])) 
    272         glTexCoord2f(0,0) 
    273         glVertex3f(*(self.x_axis[0] + [0,0,-0.5])) 
    274         glEnd() 
    275         glDisable(GL_TEXTURE_2D) 
    276  
    277         glColor4f(1,1,1,1) 
    278  
    279         def paint_grid(plane_quad, sub=20): 
    280             P11, P12, P22, P21 = numpy.asarray(plane_quad) 
     278        for axis, title in zip([self.x_axis, self.y_axis, self.z_axis], 
     279                               [self.x_axis_title, self.y_axis_title, self.z_axis_title]): 
     280            middle = (axis[0] + axis[1]) / 2. 
     281            self.renderText(middle[0], middle[1]-0.2, middle[2]-0.2, title, 
     282                            font=self.axis_title_font) 
     283 
     284        def draw_axis_plane(axis_plane, sub=10): 
     285            normal = normal_from_points(*axis_plane[:3]) 
     286            cam_in_space = numpy.array([ 
     287              self.center[0] + self.camera[0]*self.zoom, 
     288              self.center[1] + self.camera[1]*self.zoom, 
     289              self.center[2] + self.camera[2]*self.zoom 
     290            ]) 
     291            camera_vector = normalize(axis_plane[0] - cam_in_space) 
     292            cos = numpy.dot(normal, camera_vector) 
     293            cos = max(0.7, cos) 
     294            glColor4f(*(self.color_plane*cos)) 
     295            P11, P12, P21, P22 = numpy.asarray(axis_plane) 
     296            glBegin(GL_QUADS) 
     297            glVertex3f(*P11) 
     298            glVertex3f(*P12) 
     299            glVertex3f(*P21) 
     300            glVertex3f(*P22) 
     301            glEnd() 
     302            P22, P21 = P21, P22 
     303            glColor4f(*(self.color_grid * cos)) 
    281304            Dx = numpy.linspace(0.0, 1.0, num=sub) 
    282305            P1vecH = P12 - P11 
     
    290313                glVertex3f(*start) 
    291314                glVertex3f(*end) 
    292  
    293315                start = P11 + P1vecV*dx 
    294316                end = P12 + P2vecV*dx 
     
    297319            glEnd() 
    298320 
    299         def paint_quad(plane_quad): 
    300             P11, P12, P21, P22 = numpy.asarray(plane_quad) 
    301             glBegin(GL_QUADS) 
    302             glVertex3f(*P11) 
    303             glVertex3f(*P12) 
    304             glVertex3f(*P21) 
    305             glVertex3f(*P22) 
    306             glEnd() 
    307  
    308         color_plane = [0.5, 0.5, 0.5, 0.5] 
    309         color_grid = [0.3, 0.3, 0.3, 1.0] 
    310  
    311         def paint_plane(plane_quad): 
    312             glColor4f(*color_grid) 
    313             paint_grid(plane_quad) 
    314  
    315         def normal_from_points(p1, p2, p3): 
    316             v1 = p2 - p1 
    317             v2 = p3 - p1 
    318             return normalize(numpy.cross(v1, v2)) 
    319   
    320         def draw_grid_visible(plane_quad, ccw=False): 
    321             normal = normal_from_points(*plane_quad[:3]) 
    322             cam_in_space = numpy.array([ 
    323               self.center[0] + self.camera[0]*self.zoom, 
    324               self.center[1] + self.camera[1]*self.zoom, 
    325               self.center[2] + self.camera[2]*self.zoom 
    326             ]) 
    327             camera_vector = normalize(plane_quad[0] - cam_in_space) 
    328             cos = numpy.dot(normal, camera_vector) * (-1 if ccw else 1) 
    329             if cos > 0: 
    330                 paint_plane(plane_quad) 
    331  
    332         draw_grid_visible(self.axis_plane_xy) 
    333         draw_grid_visible(self.axis_plane_yz) 
    334         draw_grid_visible(self.axis_plane_xz) 
    335         draw_grid_visible(self.axis_plane_xy_back) 
    336         draw_grid_visible(self.axis_plane_yz_right) 
    337         draw_grid_visible(self.axis_plane_xz_top) 
    338  
    339         glEnable(GL_CULL_FACE) 
     321        planes = [self.axis_plane_xy, self.axis_plane_yz, 
     322                  self.axis_plane_xy_back, self.axis_plane_yz_right] 
     323        visible_planes = map(plane_visible, planes) 
     324        draw_axis_plane(self.axis_plane_xz) 
     325        for visible, plane in zip(visible_planes, planes): 
     326            if not visible: 
     327                draw_axis_plane(plane) 
     328 
     329        glDisable(GL_BLEND) 
     330 
     331        if visible_planes[0]: 
     332            draw_line(self.x_axis) 
     333            draw_values(self.x_axis, 0, numpy.array([0,0,-1])) 
     334        elif visible_planes[2]: 
     335            draw_line(self.x_axis + self.unit_z) 
     336            draw_values(self.x_axis + self.unit_z, 0, numpy.array([0,0,1])) 
     337 
     338        if visible_planes[1]: 
     339            draw_line(self.z_axis) 
     340            draw_values(self.z_axis, 2, numpy.array([-1,0,0])) 
     341        elif visible_planes[3]: 
     342            draw_line(self.z_axis + self.unit_x) 
     343            draw_values(self.z_axis + self.unit_x, 2, numpy.array([1,0,0])) 
     344 
     345        try: 
     346            rightmost_visible = visible_planes[::-1].index(True) 
     347        except ValueError: 
     348            return 
     349        if rightmost_visible == 0 and visible_planes[0] == True: 
     350            rightmost_visible = 3 
     351        y_axis_translated = [self.y_axis+self.unit_x, 
     352                             self.y_axis+self.unit_x+self.unit_z, 
     353                             self.y_axis+self.unit_z, 
     354                             self.y_axis] 
     355        normals = [numpy.array([1,0,0]), 
     356                   numpy.array([0,0,1]), 
     357                   numpy.array([-1,0,0]), 
     358                   numpy.array([0,0,-1]) 
     359                ] 
     360        axis = y_axis_translated[rightmost_visible] 
     361        draw_line(axis) 
     362        normal = normals[rightmost_visible]#normalize(((axis[1]+axis[0]) / 2.) - self.center) 
     363        draw_values(y_axis_translated[rightmost_visible], 1, normal) 
    340364 
    341365    def update_axes(self): 
     
    371395        self.axis_plane_yz_right = [B, F, G, C] 
    372396        self.axis_plane_xz_top = [E, F, B, A] 
    373  
    374         if hasattr(self, 'x_axis_frame'): 
    375           return 
    376         self.x_axis_frame = QtOpenGL.QGLFramebufferObject(256, 64) 
    377         print(self.x_axis_frame.isBound()) 
    378         self.x_axis_frame.bind() 
    379         print(self.x_axis_frame.isValid()) 
    380         glMatrixMode(GL_PROJECTION) 
    381         glLoadIdentity() 
    382         glOrtho(0,1, 0,1, -1,1) 
    383         glMatrixMode(GL_MODELVIEW) 
    384         glLoadIdentity() 
    385         glClearColor(1,0,0,1) 
    386         glClear(GL_COLOR_BUFFER_BIT) 
    387         direction = self.x_axis[1] - self.x_axis[0] 
    388         glColor3f(1,1,1) 
    389         glBegin(GL_TRIANGLES) 
    390         glVertex3f(0,0,0) 
    391         glVertex3f(1,0,0) 
    392         glVertex3f(0,1,0) 
    393         glEnd() 
    394         #for i in range(10): 
    395         #  pos = self.x_axis[0] + direction * (i / 10.) 
    396         #  self.renderText(pos[0], 10, '{0:.2}'.format(pos[0])) 
    397         self.x_axis_frame.release() 
    398397 
    399398    def scatter(self, X, Y, Z, c="b", s=5, **kwargs): 
     
    440439          vertices.extend([x,y,z, 0,+size*self.normal_size,0, r,g,b,a]) 
    441440 
    442         # It's important to keep reference to vertices around, 
    443         # data uploaded to GPU seem to get corrupted without. 
     441        # It's important to keep a reference to vertices around, 
     442        # data uploaded to GPU seem to get corrupted otherwise. 
    444443        vertex_buffer.vertices = numpy.array(vertices, 'f') 
    445444        glBufferData(GL_ARRAY_BUFFER, len(vertices)*4, 
Note: See TracChangeset for help on using the changeset viewer.