Changeset 8349:f2c07c81337c in orange
 Timestamp:
 07/04/11 20:06:07 (3 years ago)
 Branch:
 default
 Convert:
 127655484ffdab111c704f25f51f20962efce9d9
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

orange/OrangeWidgets/OWGraph3D.py
r8345 r8349 18 18 # Import undefined functions, override some wrappers. 19 19 try: 20 from OpenGL import platform21 gl = platform.OpenGL20 from OpenGL import platform 21 gl = platform.OpenGL 22 22 except ImportError: 23 try:24 gl = cdll.LoadLibrary('libGL.so')25 except OSError:26 from ctypes.util import find_library27 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) 29 29 30 30 glCreateProgram = gl.glCreateProgram … … 44 44 glVertexAttribPointer = gl.glVertexAttribPointer 45 45 glEnableVertexAttribArray = gl.glEnableVertexAttribArray 46 #glBegin = gl.glBegin47 #glEnd = gl.glEnd48 #glColor4f = gl.glColor4f49 #glColor3f = gl.glColor3f50 46 51 47 52 48 def normalize(vec): 53 return vec / numpy.sqrt(numpy.sum(vec** 2))49 return vec / numpy.sqrt(numpy.sum(vec** 2)) 54 50 55 51 … … 73 69 self.move_factor = 100. 74 70 self.mouse_pos = [100, 100] # TODO: get real mouse position, calculate camera, fix the initial jump 75 #self.update_axes()76 71 77 72 self.axis_title_font = QFont('Helvetica', 10, QFont.Bold) … … 81 76 self.z_axis_title = '' 82 77 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 83 81 self.vertex_buffers = [] 84 82 self.vaos = [] 85 83 86 84 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) 94 86 95 87 def initializeGL(self): … … 99 91 glDepthFunc(GL_LESS) 100 92 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) 104 94 105 95 self.color_shader = glCreateProgram() … … 156 146 157 147 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) 165 155 166 156 length = c_int(1) 167 157 for shader, source in zip([vertex_shader, fragment_shader], 168 158 [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 return177 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) 179 169 180 170 glBindAttribLocation(self.color_shader, 0, 'position') … … 196 186 aspect = float(self.width()) / self.height() if self.height() != 0 else 1 197 187 gluPerspective(30.0, aspect, 0.1, 100) 198 glMatrixMode(GL_MODELVIEW)199 glLoadIdentity()200 188 glMatrixMode(GL_MODELVIEW) 201 189 glLoadIdentity() … … 210 198 self.paint_axes() 211 199 200 glEnable(GL_DEPTH_TEST) 212 201 glDisable(GL_CULL_FACE) 213 202 214 203 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) 221 210 222 211 def set_x_axis_title(self, title): 223 self.x_axis_title = title224 self.updateGL()212 self.x_axis_title = title 213 self.updateGL() 225 214 226 215 def set_y_axis_title(self, title): 227 self.y_axis_title = title228 self.updateGL()216 self.y_axis_title = title 217 self.updateGL() 229 218 230 219 def set_z_axis_title(self, title): 231 self.z_axis_title = title232 self.updateGL()220 self.z_axis_title = title 221 self.updateGL() 233 222 234 223 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. 238 245 glBegin(GL_LINES) 239 glVertex3f(* start)240 glVertex3f(* end)246 glVertex3f(*line[0]) 247 glVertex3f(*line[1]) 241 248 glEnd() 242 249 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(*(positionnormal*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) 243 274 bb_center = (self.b_box[1] + self.b_box[0]) / 2. 244 275 245 276 # Draw axis labels. 246 277 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)) 281 304 Dx = numpy.linspace(0.0, 1.0, num=sub) 282 305 P1vecH = P12  P11 … … 290 313 glVertex3f(*start) 291 314 glVertex3f(*end) 292 293 315 start = P11 + P1vecV*dx 294 316 end = P12 + P2vecV*dx … … 297 319 glEnd() 298 320 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) 340 364 341 365 def update_axes(self): … … 371 395 self.axis_plane_yz_right = [B, F, G, C] 372 396 self.axis_plane_xz_top = [E, F, B, A] 373 374 if hasattr(self, 'x_axis_frame'):375 return376 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()398 397 399 398 def scatter(self, X, Y, Z, c="b", s=5, **kwargs): … … 440 439 vertices.extend([x,y,z, 0,+size*self.normal_size,0, r,g,b,a]) 441 440 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. 444 443 vertex_buffer.vertices = numpy.array(vertices, 'f') 445 444 glBufferData(GL_ARRAY_BUFFER, len(vertices)*4,
Note: See TracChangeset
for help on using the changeset viewer.