Files
2026-08-03 18:42:47 +08:00

108 lines
2.6 KiB
Python

'''
This example creates two callback objects which render a moving wave.
One is a static multi-state object, the other is a dynamic single-state
object which updates coordinates every frame.
'''
import numpy
from OpenGL.GL import *
from pymol.callback import Callback
from pymol import cmd
# define a callback object
class myCallback(Callback):
'''
Static callback object. Can be loaded into a multistate object
'''
def __init__(self, b=0):
N = 126
self.vert = numpy.zeros([N, 3], float)
self.norm = numpy.zeros([N, 3], float)
# setup x,z for vertices
self.vert[0::2, 0] = \
self.vert[1::2, 0] = numpy.arange(N / 2, dtype=float) / 10.0
self.vert[1::2, 2] = 1.0
self.update(b)
def update(self, b):
'''
update y for vertices and x,y for normals
'''
a = self.vert[0::2, 0]
x = a + b / 10.0
# vertices y
self.vert[0::2, 1] = \
self.vert[1::2, 1] = numpy.sin(x)
# normals x,y
dydx = -numpy.cos(x) * (numpy.sqrt(2.0) / 2.0)
self.norm[0::2, 0] = dydx
self.norm[0::2, 1] = numpy.sqrt(1.0 - dydx**2)
self.norm[1::2] = self.norm[0::2]
def renderDrawArrays(self):
'''
Render with glDrawArrays.
This should be faster than renderImmediate.
'''
glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_NORMAL_ARRAY)
glDisableClientState(GL_COLOR_ARRAY)
glColor3f(1.0, 1.0, 1.0)
glVertexPointer(3, GL_FLOAT, 0, self.vert)
glNormalPointer(GL_FLOAT, 0, self.norm)
glDrawArrays(GL_TRIANGLE_STRIP, 0, len(self.vert))
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
def renderImmediate(self):
'''
Render in immediate mode
'''
glBegin(GL_TRIANGLE_STRIP)
glColor3f(1.0, 1.0, 1.0)
for v, n in zip(self.vert, self.norm):
glNormal3fv(n)
glVertex3fv(v)
glEnd()
__call__ = renderImmediate
def get_extent(self):
return [
self.vert.min(0).tolist(),
self.vert.max(0).tolist(),
]
class myCallbackDynamic(myCallback):
'''
Dynamic object which updates vertex coordinates every frame
'''
def __call__(self):
self.update(cmd.get_frame() * 2)
myCallback.__call__(self)
# load it into PyMOL
for b in range(0, 63):
cmd.load_callback(myCallback(b), 'gl03', b + 1)
cmd.load_callback(myCallbackDynamic(), 'gl03dyn', 1)
# give us a nice view
cmd.turn('z',20)
cmd.turn('y',20)
cmd.turn('x',20)
cmd.mset('1-62')
cmd.mplay()