#!
# This is statement is required by the build system to query build info
if __name__ == '__build__':
raise Exception
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLE import *
from OpenGL.GLUT import *
from math import *
from Numeric import *
from random import *
import string
def loadKnot(filename):
f = open(filename)
curves = []
points = []
for line in f.readlines():
if string.lower(line[:9]) == 'component':
if len(points):
curves.append(points)
points = []
else:
try:
points.append(array(map(float, line.split())))
except:
pass
if len(points):
curves.append(points)
points = []
f.close()
return curves
def get_a(n):
a = 2.0*ones(((n+3)/2-(n%2),), Float)
a[0] = 1.0
if not n % 2:
a[-1] == 1.0
return a/n
def eval_pos(s, n, a):
return dot(a, cos(2*pi*s/n*array(range(len(a)), Float)))
def eval_loop(s, v, a):
global n, S
S = s
n = len(v)
b = fromfunction(lambda i, j: cos(2*pi/n*(S-i)*j), (n, len(a)))
return matrixmultiply(matrixmultiply(b, a), v)
def refine(points):
#~ import time
#~ n = len(points)
#~ a = get_a(n)
#~ print a
#~ s = map(lambda x: [float(x), 0.0], range(n))
#~ s[0][1] = 1.0
#~ now = time.time()
#~ pos = 0
#~ while pos < len(s):
#~ next_pos = (pos + 1) % len(s)
#~ if next_pos:
#~ next_s = s[next_pos][0]
#~ else:
#~ next_s = len(points)
#~ sample = (s[pos][0] + next_s)*0.5
#~ exact = eval_pos(sample, n, a)
#~ approx = (s[pos][1] + s[next_pos][1])*0.5
#~ if abs(exact - approx) > 0.01:
#~ s.insert(pos + 1, [sample, exact])
#~ else:
#~ pos = pos + 1
#~ print time.time() - now
#~ now = time.time()
#~ p = []
#~ for sample, pos in s:
#~ p.append(eval_loop(sample, points, a))
#~ print time.time() - now
#~ return p
p = []
for i in range(len(points)):
for j in range(10):
s = j/10.0
x = array([0.0, 0.0, 0.0])
for k in range(-1, 3):
m = 1.0
for l in range(-1, 3):
if l != k:
m = m*(s-l)/(k-l)
x = x + m*points[(k+i) % len(points)]
p.append(x)
return array(p)
class knotView:
def __init__(self, filename, width = 640, height = 480):
self.knot = loadKnot(filename)
self.colors = []
for i in range(len(self.knot)):
self.colors.append([random(), random(), random()])
self.list = None
self.phi = 0
self.theta = 0
min_x = [sys.maxint]*3
max_x = [-sys.maxint]*3
for loop in self.knot:
for x in loop:
min_x = map(min, min_x, x)
max_x = map(max, max_x, x)
center = map(lambda y, z: (y + z)*0.5, min_x, max_x)
self.radius = 0.0
for loop in self.knot:
# print loop
for x in loop:
radius2 = 0.0
for i in range(3):
x[i] = x[i] - center[i]
radius2 = radius2 + x[i]**2
self.radius = max(self.radius, sqrt(radius2))
# map(refine, self.knot)
self.knot = map(refine, self.knot)
glutInitWindowSize(width, height)
self.win = glutCreateWindow(filename)
glutDisplayFunc(self.onDisplay)
glutReshapeFunc(self.onReshape)
glutSpecialFunc(self.onSpecial)
glClearColor(1.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_CULL_FACE)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/max(float(height), 1.0), 0.1, 100.0)
glTranslatef(0, 0.0, -30.0)
# glEnable(GL_AUTO_NORMAL)
# glEnable(GL_NORMALIZE)
glMatrixMode(GL_MODELVIEW)
def onDisplay(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glShadeModel(GL_SMOOTH)
glLoadIdentity()
glRotatef(self.theta, -1, 0, 0)
glRotatef(self.phi, 0, 0, 1)
if self.list is None:
self.list = glGenLists(1)
glNewList(self.list, GL_COMPILE_AND_EXECUTE)
gleSetNumSides(50)
gleSetJoinStyle(TUBE_JN_ANGLE | TUBE_CONTOUR_CLOSED | TUBE_NORM_PATH_EDGE )# | TUBE_NORM_FACET)
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50)
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, ( 1.0, 1.0, 1.0, 1.0 ))
for i in range(len(self.knot)):
glMaterialfv(GL_FRONT, GL_DIFFUSE, self.colors[i] + [1])
loop = self.knot[i]
glePolyCylinder(loop, None, self.radius/15.0)
glEndList()
else:
glCallList(self.list)
glutSwapBuffers()
def onReshape(self, width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/max(float(height), 1.0), 0.1, 100.0)
glTranslatef(0, 0.0, -30.0)
glMatrixMode(GL_MODELVIEW)
def onSpecial(self, key, x, y):
if key == GLUT_KEY_LEFT:
self.phi = (self.phi + 358) % 360
glutPostRedisplay()
elif key == GLUT_KEY_RIGHT:
self.phi = (self.phi + 2) % 360
glutPostRedisplay()
elif key == GLUT_KEY_UP:
self.theta = (self.theta + 358) % 360
glutPostRedisplay()
elif key == GLUT_KEY_DOWN:
self.theta = (self.theta + 2) % 360
glutPostRedisplay()
if __name__ == '__main__':
import sys
args = glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
views = []
if len(args) == 1:
args.append('8.10') # use append()
for file in args[1:]: # skip first parameter
views.append(knotView(file))
glutMainLoop()
|