Statistics
| Revision:

root / PyOpenGL-Demo / proesch / nurbs / nurbs.py @ 1

History | View | Annotate | Download (5.6 kB)

1
#!/usr/bin/env python
2
# Plot nurbs surface corresponding to a 2D damped oscillation.
3
# The surface has two holes. A Teapot below the surface is
4
# visible through these holes.
5
# 
6
# Copyright (C) 2007  "Peter Roesch" <Peter.Roesch@fh-augsburg.de>
7
#
8
# This code is licensed under the PyOpenGL License.
9
# Details are given in the file license.txt included in this distribution.
10

    
11
import sys
12
import math
13
from time import sleep
14
import traceback
15

    
16
try:
17
  from OpenGL.GLUT import *
18
  from OpenGL.GL import *
19
  from OpenGL.GLU import *
20
except ImportError, err:
21
  traceback.print_exc()
22
  print ''' Error: PyOpenGL not installed properly!!'''
23
  sys.exit(  )
24

    
25
# globals
26
animationAngle = 0.0
27
frameRate = 25
28
curr_time=0.0
29
nurbsID=0
30

    
31
def animationStep( ):
32
        """Update animated parameters"""
33
        global animationAngle
34
        global frameRate
35
        animationAngle += 1
36
        while animationAngle > 360:
37
                animationAngle -= 360
38
        global curr_time
39
        curr_time+=0.05
40
        global nurbsID
41
        glDeleteLists( nurbsID, 1 )
42
        nurbsID = glGenLists( 1 )
43
        glNewList( nurbsID, GL_COMPILE )
44
        plotSurface( curr_time )
45
        glEndList( )
46
        sleep( 1 / float( frameRate ) )
47
        glutPostRedisplay( )
48

    
49
sigma = 0.5;
50
twoSigSq = 2. * sigma * sigma;
51

    
52
def dampedOscillation( u, v, t):
53
        """Calculation of a R2 -> R1 function at position u,v at curr_time t.
54

55
        A t-dependent cosine function is multiplied with a 2D gaussian.
56
        Both functions depend on the distance of (u,v) to the origin."""
57

    
58
        distSq = u * u + v * v;
59
        dist = math.pi * 4 * math.sqrt( distSq );
60
        global twoSigSq
61
        return  0.5 * math.exp(-distSq / twoSigSq) * math.cos(dist - t);
62

    
63
nPts = 15
64
degree = 4
65
samplingTolerance=2.0
66
xMin, xMax, yMin, yMax = -1.0, 1.0, -1.0, 1.0
67
xStep = (xMax-xMin)/(nPts-1)
68
yStep = (yMax-yMin)/(nPts-1)
69

    
70
# initialise a list representing a regular 2D grid of control points.
71
controlPoints = [ \
72
                [ [ yMin+y*yStep, xMin+x*xStep, 0.0 ]  for x in range ( nPts )]\
73
        for y in range( nPts ) ]
74

    
75
# initialise knots ...
76
knots = [ 0.0 for i in range( degree/2 ) ] +\
77
                                [ float(i)/(nPts-1) for i in range( nPts )] +\
78
                                [ 1.0 for i in range( (degree+1)/2 ) ]
79

    
80
# initialise enclosing
81
enclosing=[ [0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0] ]
82

    
83
# first trim curve is a circle
84
angleNum = 16
85
angles = [ -2*math.pi*float(i)/angleNum for i in range( angleNum ) ]
86
radius=0.05
87
offset=(0.4, 0.6)
88
circleDegree=degree
89
circlePoints = [ \
90
        [ offset[0]+radius*math.cos(theta), offset[1]+radius*math.sin(theta) ]\
91
        for theta in angles ]
92
for i in range( circleDegree-1 ):
93
        circlePoints = circlePoints + [ circlePoints[i] ]
94
knotNum = len( circlePoints ) + circleDegree 
95
circleKnots =  [ float(i)/(knotNum-1) for i in range( knotNum ) ]
96

    
97
# second trim curve is a square
98
squareHolePoints=[ [0.4, 0.4], [0.4, 0.45], [0.45, 0.45],\
99
        [0.45, 0.4], [0.4, 0.4] ]
100

    
101
def updateControlPoints( t ):
102
        """Calculate function values for all 2D grid points."""
103
        for row in controlPoints:
104
                for coord in row:
105
                        coord[2] = dampedOscillation( coord[0], coord[1], t )
106

    
107
def plotSurface( t ):
108
        # display surface 
109
        updateControlPoints( t )
110
        global controlPoints, knots
111
        global nurb
112

    
113
        gluBeginSurface( nurb )
114
        gluNurbsSurface        (        nurb, knots, knots, controlPoints, GL_MAP2_VERTEX_3 )
115

    
116
        # trim curve enclosing
117
        gluBeginTrim( nurb )
118
        global enclosing
119
        gluPwlCurve( nurb, enclosing, GLU_MAP1_TRIM_2 )
120
        gluEndTrim( nurb )
121

    
122
        # trim using square
123
        gluBeginTrim( nurb )
124
        global squareHolePoints
125
        gluPwlCurve( nurb, squareHolePoints, GLU_MAP1_TRIM_2 )
126
        gluEndTrim( nurb )
127
        
128
        # trim using circle
129
        gluBeginTrim( nurb )
130
        global circlePoints, circleKnots
131
        gluNurbsCurve        (        nurb, circleKnots, circlePoints, GLU_MAP1_TRIM_2 )
132
        gluEndTrim( nurb )
133

    
134
        gluEndSurface( nurb )
135
        
136

    
137
def display(  ):
138
        """Glut display function."""
139
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
140
        glMatrixMode( GL_PROJECTION )
141
        glLoadIdentity( )
142
        xSize, ySize = glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT )
143
        gluPerspective(60, float(xSize) / float(ySize), 0.1, 50)
144
        glMatrixMode( GL_MODELVIEW )
145
        glLoadIdentity( )
146
        glPushMatrix( )
147
        glTranslatef( 0, 0, -3 )
148
        glRotatef( -30, 1, .3, 0)
149
        glRotatef( animationAngle, 0, 0, 1 )
150

    
151
        glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, [0.2, 0.2, 0.2, 1] )
152
        glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, [0.7, 0.7, 0.7, 1] )
153
        glCallList( nurbsID )
154

    
155
        glPopMatrix( )
156
        glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, [0.0, 0.0, 0.2, 1] )
157
        glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, [0.0, 0.0, 0.7, 1] )
158
        glTranslatef( 0.0, 0.0, -12.0 )
159
        glCallList( teapotID )
160
        glutSwapBuffers( )
161

    
162
teapotID=0
163
nurb=None
164
def init(  ):
165
        """Glut init function."""
166
        glClearColor ( 0, 0, 0, 0 )
167
        glEnable( GL_DEPTH_TEST )
168
        glShadeModel( GL_SMOOTH )
169
        glEnable( GL_LIGHTING )
170
        glEnable( GL_LIGHT0 )
171
        glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 0 )
172
        glLightfv( GL_LIGHT0, GL_POSITION, [2, 0, 10, 1] )
173
        lA = 0.8; glLightfv( GL_LIGHT0, GL_AMBIENT, [lA, lA, lA, 1] )
174
        lD = 1; glLightfv( GL_LIGHT0, GL_DIFFUSE, [lD, lD, lD, 1] )
175
        lS = 1; glLightfv( GL_LIGHT0, GL_SPECULAR, [lS, lS, lS, 1] )
176
        glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, [0.5, 0.5, 0.5, 1] )
177
        glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 50 )
178
        glEnable( GL_AUTO_NORMAL )
179
        global nurb
180
        nurb = gluNewNurbsRenderer()
181
        global samplingTolerance
182
        gluNurbsProperty(nurb, GLU_SAMPLING_TOLERANCE, samplingTolerance)
183
        gluNurbsProperty(nurb, GLU_DISPLAY_MODE, GLU_FILL)
184
        global teapotID
185
        teapotID = glGenLists( 1 )
186
        glNewList( teapotID, GL_COMPILE )
187
        glutSolidTeapot( 1.0 )
188
        glEndList( )
189
        global nurbsID
190
        nurbsID = glGenLists( 1 )
191
        glNewList( nurbsID, GL_COMPILE )
192
        global curr_time
193
        plotSurface( curr_time )
194
        glEndList( )
195

    
196
glutInit( sys.argv )
197
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH )
198
glutInitWindowSize( 250, 250 )
199
glutInitWindowPosition( 100, 100 )
200
glutCreateWindow( sys.argv[0] )
201
init(  )
202
glutDisplayFunc( display )
203
glutIdleFunc( animationStep )
204
glutMainLoop(  )