Scenegraph Nodes: Molehill NURBS Introduction
#! /usr/bin/env python
from OpenGLContext import testingcontext
BaseContext = testingcontext.getInteractive()
from OpenGL.GL import *
from OpenGLContext.arrays import *
import string, time
from OpenGLContext.scenegraph.basenodes import *
from OpenGLContext.scenegraph import nurbs
class TestContext( BaseContext ):
def buildControlPoints( self ):
"""Build control points for NURBS mole hills"""
Normally you would use a 3D modeller to create nurbs
geometry, but we'll generate it by paper-and-pencil method
(actually, Mark Kilgard did in 1995, we're just copying the
setup here).
pts1 = []
pts2 = []
pts3 = []
pts4 = []
for u in range(4):
pts1.append([])
pts2.append([])
pts3.append([])
pts4.append([])
for v in range(4):
Red surface
pts1[u].append([2.0*u, 2.0*v, 0.0])
if (u == 1 or u == 2) and (v == 1 or v == 2):
pts1[u][v][2] = 6.0
Green surface
pts2[u].append([2.0*u - 6.0, 2.0*v - 6.0, 0.0])
if (u == 1 or u == 2) and (v == 1 or v == 2):
if u == 1 and v == 1:
Pull hard on single middle square.
pts2[u][v][2] = 15.0
else:
Push down on other middle squares.
pts2[u][v][2] = -2.0
Blue surface
pts3[u].append([2.0*u - 6.0, 2.0*v, 0.0])
if (u == 1 or u == 2) and (v == 1 or v == 2):
if u == 1 and v == 2:
Pull up on single middle square.
pts3[u][v][2] = 11.0
else:
Pull up slightly on other middle squares.
pts3[u][v][2] = 2.0
Yellow surface
pts4[u].append([2.0*u, 2.0*v - 6.0, 0.0])
if u != 0 and (v == 1 or v == 2):
if v == 1:
Push down front middle and right squares.
pts4[u][v][2] = -2.0
else:
Pull up back middle and right squares.
pts4[u][v][2] = 5.0
Stretch up red's far right corner.
pts1[3][3][2] = 6.0
Pull down green's near left corner a little.
pts2[0][0][2] = -2.0
Turn up meeting of four corners.
pts1[0][0][2] = 1.0
pts2[3][3][2] = 1.0
pts3[3][0][2] = 1.0
pts4[0][3][2] = 1.0
return pts1,pts2,pts3,pts4
def OnInit( self ):
"""Create the scenegraph for rendering"""
print """You should see a 4-colour "molehill" composed of four different NurbsSurface nodes."""
knots = array( (0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0),'f' )
pts1,pts2,pts3,pts4 = self.buildControlPoints()
colors = [[1,0,0],[0,1,0],[0,0,1],[1,1,0],]
All of the shapes have the same structure (number of knots
in both u and v dimensions). They only vary in the control
points and colours with which we will render them.
self.shapes = []
for pts,color in zip((pts1,pts2,pts3,pts4),colors):
appearance = Appearance(
material = Material(
diffuseColor = color,
),
)
The actual NURBS surfaces are simple NurbsSurface
instances, with no trimming or other complex operations.
self.shapes.append(
Shape(
appearance = appearance,
geometry = NurbsSurface(
controlPoint = pts,
vDimension = 4,
uDimension = 4,
uKnot = knots,
vKnot = knots,
),
)
)
Here we render the control points so you can see them in
relation to the surface.
self.shapes.append(
Shape(
geometry = PointSet(
coord = Coordinate(
point = pts,
),
),
)
)
Scenegraph is transformed so that the initial view looks
approximately like the original code
self.sg = sceneGraph(
children = [
Transform(
scale = [.5,.5,.5],
rotation = [1,0,0,-.5],
children = self.shapes,
),
],
)
if __name__ == "__main__":
TestContext.ContextMainLoop()
Original Demo:
Copyright (c) Mark J. Kilgard, 1995
This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain.
molehill uses the GLU NURBS routines to draw some nice surfaces.
Molehill NURBS Introduction