#!/usr/bin/env python # -*- coding: iso-8859-1 -*- #url: http://showmedo.com/videotutorials/video?name=1510030&fromSeriesID=151 import wx import sys from wx import glcanvas from OpenGL.GL import * from OpenGL.GLU import * from nurbs import NurbsCurve, Circle import Numeric import numpy array = numpy.array torusnurbpts = [ 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0, 2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0, 2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0, 1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,-2.0,-2.0, 0.0, 2.0, -1.0,-1.0, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0, -2.0,-2.0,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0, -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0, -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0, -4.0, 0.0, 0.0, 4.0,-2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0, -2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0, -1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0, 2.0, 2.0, 0.0, 2.0, 1.0, 1.0, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0, 2.0, 2.0,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0, 4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0 ] circleknots = [0.0, 0.0, 0.0, 0.25, 0.50, 0.50, 0.75, 1.0, 1.0, 1.0] def sign(number): return cmp(number, 0) class MyCanvasBase(glcanvas.GLCanvas): def __init__(self, parent): glcanvas.GLCanvas.__init__(self, parent, -1, attribList=[wx.glcanvas.WX_GL_DOUBLEBUFFER]) self.parent = parent #just for safe keeping self.init = False #initial mouse position self.lastx = self.x = 30 self.lasty = self.y = 30 self.size = None self.zoom = 1 self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown) self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp) self.Bind(wx.EVT_MOTION, self.OnMouseMotion) self.Bind(wx.EVT_MOUSEWHEEL, self.OnWheel) def OnEraseBackground(self, event): pass #do nothing, to avoid flashing on MSW. def OnSize(self, event): size = self.size = self.GetClientSize() self.width, self.height = event.GetSize() if self.GetContext(): self.SetCurrent() self.InitGL() #glViewport(0, 0, size.width, size.height) #glViewport(0, 0, 300, 300) #self.OnPaint(event) event.Skip() def OnPaint(self, event): dc = wx.PaintDC(self) self.SetCurrent() if not self.init: self.InitGL() self.init = True self.OnDraw() def OnMouseDown(self, evt): self.CaptureMouse() self.x, self.y = self.lastx, self.lasty = evt.GetPosition() def OnMouseUp(self, evt): self.ReleaseMouse() def OnMouseMotion(self, evt): if evt.Dragging() and evt.LeftIsDown(): self.lastx, self.lasty = self.x, self.y self.x, self.y = evt.GetPosition() self.Refresh(False) def OnWheel(self, evt): if evt.GetWheelRotation() != 0: self.zoom = self.zoom + (sign(evt.GetWheelRotation()) * 1) print "wheel rotation: ", evt.GetWheelRotation() print "zoom: ", self.zoom self.InitGL() self.OnDraw() self.Refresh(False) class CubeCanvas(MyCanvasBase): def InitGL(self): glClearColor(0, 0, 0, 1) glClearDepth(1) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) glEnable(GL_COLOR_MATERIAL) #natural_width = 800 #natural_height = 600 #glViewport(0, 0, natural_width, natural_height) glViewport(0, 0, self.width, self.height) glMatrixMode(GL_PROJECTION) glLoadIdentity() height = self.height width = self.width #natural_height = height #natural_width = width #view_angle = 60 # float(height) / natural_height * 45 #ratio_w_h = float(width) / height #clip_close = float(0.1) #clip_far = 1000 #gluPerspective(view_angle, ratio_w_h, clip_close, clip_far) centerx = 0 centery = 0 diam = 10 #zoom2 = self.zoom #if zoom2 == 0: zoom2 = 1 #diam = zoom2 # #if zoom2 <= -1: # diam = 1 - 1/zoom2 left = centerx - diam right = centerx + diam bottom = centery - diam top = centery + diam zNear = 1 zFar = 200 #correct resizing, wrong circles #glOrtho(-width/2, width/2, -height/2, height/2, zNear, zFar) #glOrtho(-(width-diam)/2, (width+diam)/2, -(height-diam)/2, (height+diam)/2, zNear, zFar) glOrtho(-width/2 - diam, width/2 + diam, -height/2 - diam, height/2 + diam, zNear, zFar) #correct circles, wrong resizing #glOrtho(left, right, bottom, top, zNear, zFar) #glOrtho(-10, 10, -10, 10, zNear, zFar) #all wrong #glOrtho(0, width, 0, height, zNear, zFar) #centered, correct resizing, wrong circles #glOrtho(-width, width, -height, height, zNear, zFar) print "width: ", width print "height: ", height ##glOrtho(0 - self.width, 0 + self.width, 0 - self.height, 0 + self.height, zNear, zFar) glMatrixMode(GL_MODELVIEW) glLoadIdentity() nurb = gluNewNurbsRenderer() gluNurbsProperty(nurb, GLU_SAMPLING_TOLERANCE, 1.) gluNurbsProperty(nurb, GLU_DISPLAY_MODE, GLU_FILL) glNewList(1, GL_COMPILE) glMaterialfv(GL_FRONT, GL_SPECULAR, ( 1.0, 1.0, 1.0, 1.0 )) glMaterialfv(GL_FRONT, GL_SHININESS, 100.0) glMaterialfv(GL_FRONT, GL_DIFFUSE, ( 0.7, 0.0, 0.1, 1.0 )) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_DEPTH_TEST) glEnable(GL_AUTO_NORMAL) glEnable(GL_NORMALIZE) #xcircle = Crv.Circle(radius=10) #xsrf = Srf.Extrude(xcircle, [0, 0, 10]) circle = Circle(radius=10) #circle = Crv.Line(p1=(0,0,0), p2=(1,1,1)) #srf = Srf.Ruled(crv1, crv2) #circle.cntrl[2][0] = -5 srf = circle.extrude([0, 0, 10]) #import pdb; pdb.set_trace(); #srf.cntrl[3][0][0] = 5 gluBeginSurface(nurb) gluNurbsSurface(nurb, srf.uknots, srf.vknots, Numeric.transpose(srf.cntrl, (1,2,0)), GL_MAP2_VERTEX_4) gluEndSurface(nurb) glEndList() glNewList(2, GL_COMPILE) # draw six faces of a cube glBegin(GL_QUADS) glNormal3f( 0.0, 0.0, 1.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glNormal3f( 0.0, 0.0,-1.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glNormal3f( 0.0, 1.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5,-0.5) glVertex3f(-0.5, 0.5, 0.5) glNormal3f( 0.0,-1.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f(-0.5,-0.5, 0.5) glNormal3f( 1.0, 0.0, 0.0) glVertex3f( 0.5, 0.5, 0.5) glVertex3f( 0.5,-0.5, 0.5) glVertex3f( 0.5,-0.5,-0.5) glVertex3f( 0.5, 0.5,-0.5) glNormal3f(-1.0, 0.0, 0.0) glVertex3f(-0.5,-0.5,-0.5) glVertex3f(-0.5,-0.5, 0.5) glVertex3f(-0.5, 0.5, 0.5) glVertex3f(-0.5, 0.5,-0.5) glEnd() glEndList() glNewList(3, GL_COMPILE) cntrl = [[-5., -7.5, 2.5, 0, -2.5, 7.5, 5.0], [2.5, 5.0, 5.0, .0, -5.0, -5.0, 2.5]] knots = [0., 0., 0., .2, .4, .6, .8, 1., 1., 1.] #crv = Crv.Crv(cntrl, knots) #crv = Crv.Circle(radius=5) crv = Circle(radius=10) #crv = Crv.Line(p1=(0,0,0), p2=(10,10,10)) glPointSize(10.) glDisable(GL_LIGHTING) #set color to white glColor3f(1., 1., 1.) #draw white points glBegin(GL_POINTS) for i in range(crv.control_points.shape[1]): w = crv.control_points[-1,i] glVertex3f(crv.control_points[0, i]/w, crv.control_points[1, i]/w, crv.control_points[2, i]/w) glEnd() #draw the polygon connecting the points glBegin(GL_LINE_STRIP) for i in range(crv.control_points.shape[1]): w = crv.control_points[-1,i] glVertex3f(crv.control_points[0, i]/w, crv.control_points[1, i]/w, crv.control_points[2, i]/w) glEnd() #circle glColor3f(1., 0., 0.) nurb2 = gluNewNurbsRenderer() gluNurbsProperty(nurb2, GLU_SAMPLING_TOLERANCE, 1) gluBeginCurve(nurb2) gluNurbsCurve(nurb2, crv.knots, Numeric.transpose(crv.control_points), GL_MAP1_VERTEX_4) gluEndCurve(nurb2) #circular_surface = crv.extrude([0, 0, 10]) #gluBeginSurface(nurb2) #gluNurbsSurface(nurb2, circular_surface.uknots, circular_surface.vknots, Numeric.transpose(circular_surface.control_points, (1,2,0)), GL_MAP2_VERTEX_4) #gluEndSurface(nurb2) #everything else should be yellow glColor3f(1., 1., 0.) glEndList() def OnDraw(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glMatrixMode(GL_MODELVIEW) glLoadIdentity() zoom2 = self.zoom if zoom2 == 0: zoom2 = 1 if zoom2 <= -1: zoom2 = -1/float(zoom2) glScalef(zoom2, zoom2, 1) print "zoom factor is: ", zoom2 #move it back a bit glTranslatef(0, 0, -15) #mouse click rotation glRotatef(self.lastx, 0.0, 1.0, 0.0) glRotatef(self.lasty, 1.0, 0.0, 0.0) glCallList(1) glCallList(3) factor = 5 glScalef(factor, factor, factor) glCallList(2) self.SwapBuffers() class MainWindow(wx.Frame): def __init__(self, parent = None, id = -1, title = "lolcad"): wx.Frame.__init__( self, parent, id, title, size = (480,320), style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE ) #TextCtrl #self.control = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE) box = wx.BoxSizer(wx.HORIZONTAL) #self.cone_canvas = ConeCanvas(self) self.cube_canvas = CubeCanvas(self) #box.Add(self.cone_canvas, 1, wx.EXPAND) box.Add(self.cube_canvas, 1, wx.EXPAND) self.SetSizer(box) #self.SetAutoLayout(True) #default self.Show(True) def OnAbout(self,event): message = "Using PyOpenGL in wxPython" caption = "About PyOpenGL Example" wx.MessageBox(message, caption, wx.OK) def OnExit(self,event): self.Close(True) #close the frame app = wx.PySimpleApp() frame = MainWindow() app.MainLoop() #destroying the objects, so that this script works more than once in IDLEdieses Beispiel #del frame #del app