1
2
3
4
5 """OpenGL rendering classes.
6 """
7 import sys
8 import copy
9 import math
10
11 try:
12 import numpy
13 try:
14 from numpy.oldnumeric import linear_algebra as linalg
15 except ImportError:
16 from numpy.linalg import old as linalg
17 except ImportError:
18 import NumericCompat as numpy
19 from NumericCompat import linalg
20
21 from OpenGL.GL import *
22 from OpenGL.GLU import *
23 from OpenGL.GLUT import *
24
25 import ConsoleOutput
26 import Gaussian
27 import AtomMath
28
29 try:
30 import glaccel
31 except ImportError:
32 ConsoleOutput.warning("cannot load OpenGL acceloration module glaccel")
33 GLACCEL_EXISTS = False
34 else:
35 GLACCEL_EXISTS = True
36
37
39 """OpenGL render driver for Viewer.py
40 """
62
64 """Returns True if draw compiling is supported by the driver.
65 """
66 return True
67
69 """
70 """
71 mid = id(draw_method)
72 expiration_id = draw_method["expiration_id"]
73 assert mid not in self.gl_draw_list_id
74
75 draw_list_id = glGenLists(1)
76 self.gl_draw_list_id[mid] = draw_list_id
77 self.gl_draw_list_expiration_id[mid] = expiration_id
78 glNewList(draw_list_id, GL_COMPILE)
79
80 return mid
81
83 """
84 """
85 glEndList()
86
88 """
89 """
90 mid = id(draw_method)
91 assert mid in self.gl_draw_list_id
92
93 draw_list_id = self.gl_draw_list_id[mid]
94 glDeleteLists(draw_list_id, 1)
95 del self.gl_draw_list_id[mid]
96 del self.gl_draw_list_expiration_id[mid]
97
99 """
100 """
101 mid = id(draw_method)
102 return mid in self.gl_draw_list_id
103
105 """
106 """
107 mid = id(draw_method)
108 expiration_id = draw_method["expiration_id"]
109 assert mid in self.gl_draw_list_id
110 return self.gl_draw_list_expiration_id[mid]==expiration_id
111
113 """
114 """
115 mid = id(draw_method)
116 assert mid in self.gl_draw_list_id
117
118 draw_list_id = self.gl_draw_list_id[mid]
119 glCallList(draw_list_id)
120
121 - def glr_render_begin(
122 self,
123 width = 200,
124 height = 100,
125 zoom = 50,
126 near = 0,
127 far = 0,
128 bg_color_rgbf = (0.0, 0.0, 0.0),
129 ambient_light = 1.0,
130 diffuse_light = 1.0,
131 specular_light = 1.0,
132 gl_line_smooth = False,
133 gl_point_smooth = False,
134 gl_polygon_smooth = False,
135 gl_blend = True,
136 gl_fog = False,
137 gl_fog_start = 0.0,
138 gl_fog_end = 0.0,
139 **args):
140 """Sets up lighting and OpenGL options before scene rendering.
141 """
142 glViewport(0, 0, width, height)
143
144
145 glMatrixMode(GL_PROJECTION)
146 glLoadIdentity()
147
148 zoom = zoom / 2.0
149 ratio = float(height) / float(width)
150 depth = near - far
151
152 self.near = near
153 glOrtho(-zoom, zoom, -ratio*zoom, ratio*zoom, 0.0, depth)
154
155
156
157 glMatrixMode(GL_MODELVIEW)
158 glLoadIdentity()
159 glTranslatef(0.0, 0.0, -near)
160
161
162 glEnable(GL_NORMALIZE)
163 glShadeModel(GL_SMOOTH)
164 glEnable(GL_DEPTH_TEST)
165 glDepthFunc(GL_LESS)
166
167
168 glClearColor(bg_color_rgbf[0], bg_color_rgbf[1], bg_color_rgbf[2], 0.0)
169 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)
170
171
172 ambient = (ambient_light, ambient_light, ambient_light, 1.0)
173 diffuse = (diffuse_light, diffuse_light, diffuse_light, 1.0)
174 specular = (specular_light, specular_light, specular_light, 1.0)
175
176
177 glEnable(GL_LIGHT0)
178 glLightfv(GL_LIGHT0, GL_AMBIENT, (0.0, 0.0, 0.0, 1.0))
179 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse)
180 glLightfv(GL_LIGHT0, GL_SPECULAR, specular)
181 glLightfv(GL_LIGHT0, GL_POSITION, (50.0, 50.0, 1000.0, 0.0))
182
183
184 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient)
185
186
187 self.glr_light_two_sides_disable()
188
189
190 glDisable(GL_LIGHT1)
191
192
193 if gl_line_smooth:
194 glEnable(GL_LINE_SMOOTH)
195 else:
196 glDisable(GL_LINE_SMOOTH)
197
198 if gl_point_smooth:
199 glEnable(GL_POINT_SMOOTH)
200 else:
201 glDisable(GL_POINT_SMOOTH)
202
203 if gl_polygon_smooth:
204 glEnable(GL_POLYGON_SMOOTH)
205 else:
206 glDisable(GL_POLYGON_SMOOTH)
207
208
209 if gl_blend:
210 glEnable(GL_BLEND)
211 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
212
213
214 if gl_fog:
215 glEnable(GL_FOG)
216 glFogf(GL_FOG_MODE, GL_LINEAR)
217 glFogfv(GL_FOG_COLOR, (bg_color_rgbf[0], bg_color_rgbf[1],
218 bg_color_rgbf[2], 0.0))
219 glFogf(GL_FOG_START, 0.0)
220 glFogf(GL_FOG_END, depth)
221 else:
222 glDisable(GL_FOG)
223 else:
224 glDisable(GL_BLEND)
225
227 """
228 """
229 glTranslatef(0.0, 0.0, self.near)
230 del self.near
231
233 """
234 """
235 glPushMatrix()
236
238 """
239 """
240 glPopMatrix()
241
243 """Translates the scene by vector t.
244 """
245 glTranslatef(*t)
246
248 """
249 """
250 glTranslatef(x, y, z)
251
253 """Return the current matrix as a 3x3 rotation matrix R and 3x1
254 translation vector t.
255 """
256
257 glMultMatrixf(
258 (R[0,0], R[1,0], R[2,0], 0.0,
259 R[0,1], R[1,1], R[2,1], 0.0,
260 R[0,2], R[1,2], R[2,2], 0.0,
261 t[0], t[1], t[2], 1.0) )
262
264 """Multiplies the current matrix by rotation matrix R and translates
265 by t
266 """
267
268 glMultMatrixf(
269 (R[0,0], R[1,0], R[2,0], 0.0,
270 R[0,1], R[1,1], R[2,1], 0.0,
271 R[0,2], R[1,2], R[2,2], 0.0,
272 0.0, 0.0, 0.0, 1.0) )
273
275 """
276 """
277 glRotatef(deg, *axis)
278
280 """
281 """
282 glEnable(GL_LIGHTING)
283
285 """
286 """
287 glDisable(GL_LIGHTING)
288
290 """
291 """
292 glLineWidth(width)
293
295 """
296 """
297 glBegin(GL_LINES)
298
300 """
301 """
302 self.vertex_draw_type = "triangles"
303
305 """
306 """
307 glBegin(GL_TRIANGLE_FAN)
308
310 """
311 """
312 glBegin(GL_QUADS)
313
315 """
316 """
317 glEnd()
318
320 """
321 """
322 glEnable(GL_NORMALIZE)
323
325 """
326 """
327 glDisable(GL_NORMALIZE)
328
330 """
331 """
332 glNormal3f(*n)
333
335 """
336 """
337 glNormal3f(x, y, z)
338
340 """
341 """
342 self.gl_light_model_two_side = True
343 glDisable(GL_CULL_FACE)
344 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE)
345 self.glr_set_material_rgba(
346 self.material_r,
347 self.material_g,
348 self.material_b,
349 self.material_a)
350
352 """
353 """
354 self.gl_light_model_two_side = False
355 glEnable(GL_CULL_FACE)
356 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE)
357 self.glr_set_material_rgba(
358 self.material_r,
359 self.material_g,
360 self.material_b,
361 self.material_a)
362
364 """Creates a stock rendering material colored according to the given
365 RGB values.
366 """
367 self.material_r = r
368 self.material_g = g
369 self.material_b = b
370 self.material_a = 1.0
371
372 glColor3f(r, g, b)
373
374 ambient = (r, g, b, 1.0)
375 diffuse = (r, g, b, 1.0)
376 specular = (1.0, 1.0, 1.0, 1.0)
377 emission = (0.1*r, 0.1*g, 0.1*b, 1.0)
378
379 if self.gl_light_model_two_side==True:
380 side = GL_FRONT_AND_BACK
381 else:
382 side = GL_FRONT
383
384 glMaterialfv(side, GL_AMBIENT, ambient)
385 glMaterialfv(side, GL_DIFFUSE, diffuse)
386 glMaterialfv(side, GL_SPECULAR, specular)
387 glMaterialfv(side, GL_EMISSION, emission)
388 glMaterialfv(side, GL_SHININESS, 100.0)
389
391 """Creates a stock rendering material colored according to the given
392 RGB values.
393 """
394 self.material_r = r
395 self.material_g = g
396 self.material_b = b
397 self.material_a = a
398
399 glColor3f(r, g, b)
400
401 ambient = (r, g, b, a)
402 diffuse = (r, g, b, a)
403 specular = (1.0, 1.0, 1.0, a)
404 emission = (0.1*r, 0.1*g, 0.1*b, a)
405
406 if self.gl_light_model_two_side==True:
407 side = GL_FRONT_AND_BACK
408 else:
409 side = GL_FRONT
410
411 glMaterialfv(side, GL_AMBIENT, ambient)
412 glMaterialfv(side, GL_DIFFUSE, diffuse)
413 glMaterialfv(side, GL_SPECULAR, specular)
414 glMaterialfv(side, GL_EMISSION, emission)
415 glMaterialfv(side, GL_SHININESS, 100.0)
416
418 """
419 """
420 glVertex3f(*position)
421
423 """
424 """
425 glVertex3f(x, y, z)
426
427 - def glr_line(self, position1, position2):
428 """Draws a single line.
429 """
430 glBegin(GL_LINES)
431 glVertex3f(*position1)
432 glVertex3f(*position2)
433 glEnd()
434
435 - def glr_text(self, text, scale):
436 """Renders a text string.
437 """
438 glDisable(GL_LIGHTING)
439 glLineWidth(2.0)
440
441 glPushMatrix()
442
443 s = scale / 1000.0
444 glScalef(s, s, s)
445
446 for c in text:
447 glutStrokeCharacter(GLUT_STROKE_ROMAN, ord(c))
448
449 glPopMatrix()
450
451 - def glr_axis(self, position, axis, radius):
452 """Draw a vector axis using the current set material at position
453 with the given radius.
454 """
455
456 if numpy.allclose(AtomMath.length(axis), 0.0):
457 return
458
459 end = position + axis
460
461 l = AtomMath.length(axis)
462 R = AtomMath.rmatrixz(axis)
463
464 glPushMatrix()
465 self.glr_mult_matrix_Rt(R, position)
466
467 glEnable(GL_LIGHTING)
468
469 quad = gluNewQuadric()
470 gluCylindar(quad, radius, radius, l, 10, 1)
471
472 glDisable(GL_LIGHTING)
473 glPopMatrix()
474
476 """glaccel optimized version of glr_axis.
477 """
478 if numpy.allclose(AtomMath.length(axis), 0.0):
479 return
480 end = position + axis
481 glaccel.rod(position[0], position[1], position[2], end[0], end[1], end[2], radius)
482
483 - def glr_tube(self, pos1, pos2, radius):
484 """Draws a hollow tube beginning at pos1, and ending at pos2.
485 """
486 glDisable(GL_LIGHTING)
487 glLineWidth(1.0)
488 glBegin(GL_LINES)
489 glVertex3f(*pos1)
490 glVertex3f(*pos2)
491 glEnd()
492
494 glaccel.tube(
495 pos1[0], pos1[1], pos1[2],
496 pos2[0], pos2[1], pos2[2],
497 radius)
498
500 """Draws a solid sphere.
501 """
502 glEnable(GL_LIGHTING)
503 glPushMatrix();
504 glTranslatef(*position)
505 glutSolidSphere(radius, quality, quality)
506 glPopMatrix()
507
509 glaccel.sphere(position[0], position[1], position[2], radius, quality)
510
511 - def glr_cross(self, position, color, line_width):
512 """Draws atom with a cross of lines.
513 """
514 glDisable(GL_LIGHTING)
515 glColor3f(*color)
516 glLineWidth(line_width)
517
518 vx = numpy.array([0.25, 0.0, 0.0])
519 vy = numpy.array([0.0, 0.25, 0.0])
520 vz = numpy.array([0.0, 0.0, 0.25])
521
522 glBegin(GL_LINES)
523
524 start = position - vx
525 end = position + vx
526 glVertex3f(*start)
527 glVertex3f(*end)
528
529 start = position - vy
530 end = position + vy
531 glVertex3f(*start)
532 glVertex3f(*end)
533
534 start = position - vz
535 end = position + vz
536 glVertex3f(*start)
537 glVertex3f(*end)
538
539 glEnd()
540
541 - def glr_Uaxes(self, position, U, prob, color, line_width):
542 """Draw the anisotropic axies of the atom at the given probability.
543 """
544 C = Gaussian.GAUSS3C[prob]
545 eval_U, evec_U = linalg.eignvectors(U)
546
547 try:
548 v0_peak = C * math.sqrt(eval_U[0])
549 except ValueError:
550 v0_peak = 0.0
551 try:
552 v1_peak = C * math.sqrt(eval_U[1])
553 except ValueError:
554 v1_peak = 0.0
555 try:
556 v2_peak = C * math.sqrt(eval_U[2])
557 except ValueError:
558 v2_peak = 0.0
559
560 v0 = evec_U[0] * v0_peak
561 v1 = evec_U[1] * v1_peak
562 v2 = evec_U[2] * v2_peak
563
564 glDisable(GL_LIGHTING)
565 glColor3f(*color)
566 glLineWidth(line_width)
567
568 glPushMatrix()
569 glTranslatef(*position)
570
571 glBegin(GL_LINES)
572 glVertex3f(*-v0)
573 glVertex3f(* v0)
574 glVertex3f(*-v1)
575 glVertex3f(* v1)
576 glVertex3f(*-v2)
577 glVertex3f(* v2)
578 glEnd()
579
580 glPopMatrix()
581
583 """Renders the ellipsoid enclosing the given fractional probability
584 given the gaussian variance-covariance matrix U at the given position.
585 C=1.8724 = 68%
586 """
587 pass
588
590 """Renders the ellipsoid enclosing the given fractional probability
591 given the gaussian variance-covariance matrix U at the given position.
592 C=1.8724 = 68%
593 """
594 glaccel.Uellipse(
595 position[0], position[1], position[2],
596 U[0,0], U[1,1], U[2,2], U[0,1], U[0,2], U[1,2],
597 Gaussian.GAUSS3C[prob], 3)
598
600 """Renders the root mean square (one standard deviation) surface of
601 the gaussian variance-covariance matrix U at the given position. This
602 is a peanut-shaped surface. (Note: reference the peanut paper!)
603 """
604 pass
605
607 """Renders the root mean square (one standard deviation) surface of
608 the gaussian variance-covariance matrix U at the given position. This
609 is a peanut-shaped surface. (Note: reference the peanut paper!)
610 """
611 glaccel.Upeanut(
612 position[0], position[1], position[2],
613 U[0,0], U[1,1], U[2,2], U[0,1], U[0,2], U[1,2],
614 3)
615