def __init__(self): ## openGL context configuration stencil_size = 8 depth_size = 16 samples = 4 sample_buffers = 1 platform = pyglet.window.get_platform() display = platform.get_default_display() screen = display.get_default_screen() templateHigh = pyglet.gl.Config(sample_buffers=sample_buffers, samples = samples, double_buffer=True, depth_size = depth_size, stencil_size = stencil_size) templateLow = pyglet.gl.Config(sample_buffers=0, double_buffer=False, depth_size = 16) try: config = screen.get_best_config(templateHigh) except pyglet.window.NoSuchConfigException: try: config = screen.get_best_config(templateLow) print "OpenGlconfig", config except pyglet.window.NoSuchConfigException: print " OpenGL: simple context configuration is applied due to installed hardware" template = gl.Config() config = screen.get_best_config(template) print "OpenGlconfig", config context = config.create_context(None) super(Visualisation3DGUI, self).__init__(resizable = True, context = context) self.set_maximum_size(screen.width, screen.height) self.set_minimum_size(self.width, self.height) self.keys = key.KeyStateHandler() self.push_handlers(self.keys) self.backgroundColorIterator = 0 self.backgroundColors = [[1.0,1.0,1.0,1], [0.95,0.95,0.95,1], [0.85,0.85,0.85,1], [0.75,0.75,0.75,1]] self.backgroundColor = [0.75,0.75,0.75,1] pyglet.gl.glClearColor(*self.backgroundColor) self.batch = pyglet.graphics.Batch() self.beta = (pi*5.)/180. self.alpha = (pi*5.)/180. self.dalpha = (pi*5.)/180. self.cameraEyesInit = np.array([4.,0.,0.]) self.cameraLookAtInit = np.array([0.,0.,0.]) self.cameraEyes = np.copy(self.cameraEyesInit) self.cameraLookAt = np.copy(self.cameraLookAtInit) self.normal = np.array([0.,0.,0.]) #self.viewUp = np.array([-0.70710678 , 0., 0.70710678]) # 45 degree self.viewUp = np.array([0 , 0., 1]) self.axisX = np.array([1.,0.,0]) self.axisY = np.array([0.,1.,0]) self.axisZ = np.array([0.,0.,1]) self.viewZoomingSensitivity = 0.5 self.viewTranslateSensitivityX = 0.001 self.viewTranslateSensitivityY = 0.0005 self.viewRotationSensitivityZ = self.dalpha ### # simulation runtime variables self.simulationRunning = False self.clock = pyglet.clock.get_default() self.updateTime = 1./60. # One-time GL setup glColor3f(1, 0, 0) glEnable(GL_DEPTH_TEST) ## uncomment this line for viewing only front faces #glEnable(GL_CULL_FACE) # Uncomment this line for a wireframe view #glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) # Simple light setup. On Windows GL_LIGHT0 is enabled by default, # but this is not the case on Linux or Mac, so remember to always # include it. glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_LIGHT1) # Define a simple function to create ctypes arrays of floats: def vec(*args): return (GLfloat * len(args))(*args) glLightfv(GL_LIGHT0, GL_POSITION, vec(.5, .5, 1, 0)) glLightfv(GL_LIGHT0, GL_SPECULAR, vec(.5, .5, 1, 1)) glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(1, 1, 1, 1)) glLightfv(GL_LIGHT1, GL_POSITION, vec(1, 0, .5, 0)) glLightfv(GL_LIGHT1, GL_DIFFUSE, vec(.5, .5, .5, 1)) glLightfv(GL_LIGHT1, GL_SPECULAR, vec(1, 1, 1, 1)) ### # control GUI window self.controlWindow = ControlWindow(self) # register button events # simulation speed self.controlWindow.onPressRealTimeSim = self.visualisationSpeedRealTime self.controlWindow.onPressHalfTimeSim = self.visualisationSpeedHalfTime self.controlWindow.onChangeSpeedSlider = self.setVisualisationSpeed # view self.controlWindow.onPressViewXY = self.setViewXY self.controlWindow.onPressViewYZ = self.setViewYZ self.controlWindow.onPressViewXZ = self.setViewXZ self.controlWindow.onPressViewXYZ = self.setViewXYZ # play pause / reset self.controlWindow.onPressPlayPause = self.startVisualisation self.controlWindow.onPressReset = self.resetVisualisationAndPause # create movie self.controlWindow.onPressMovie = self.recordMovie self.controlWindow.onPressViewPhoto = self.saveScreenShot # LUT self.controlWindow.onPressLookUpTable = self.changeColorTable self.controlWindow.onPressChangeQuantity = self.changeQuantityLUT # wave split self.controlWindow.onPressSplit = self.enableWaveSplitLookUp self.controlWindow.onPressSplitExp = self.enableLeftRightColoring # vessel area/wall movement self.controlWindow.onPressWallMovement = self.enableWallMovement self.controlWindow.onChangeWallSlider = self.setAreaFactor self.controlWindow.onPressBackgroundColor = self.changeBackgroundColor
class Visualisation3DGUI(pyglet.window.Window): ''' This class defines the GuI inclusive call buttons (saparete GUI class to Gui-user Class which is then wrapped into Visualisation3D ) ''' def __init__(self): ## openGL context configuration stencil_size = 8 depth_size = 16 samples = 4 sample_buffers = 1 platform = pyglet.window.get_platform() display = platform.get_default_display() screen = display.get_default_screen() templateHigh = pyglet.gl.Config(sample_buffers=sample_buffers, samples = samples, double_buffer=True, depth_size = depth_size, stencil_size = stencil_size) templateLow = pyglet.gl.Config(sample_buffers=0, double_buffer=False, depth_size = 16) try: config = screen.get_best_config(templateHigh) except pyglet.window.NoSuchConfigException: try: config = screen.get_best_config(templateLow) print "OpenGlconfig", config except pyglet.window.NoSuchConfigException: print " OpenGL: simple context configuration is applied due to installed hardware" template = gl.Config() config = screen.get_best_config(template) print "OpenGlconfig", config context = config.create_context(None) super(Visualisation3DGUI, self).__init__(resizable = True, context = context) self.set_maximum_size(screen.width, screen.height) self.set_minimum_size(self.width, self.height) self.keys = key.KeyStateHandler() self.push_handlers(self.keys) self.backgroundColorIterator = 0 self.backgroundColors = [[1.0,1.0,1.0,1], [0.95,0.95,0.95,1], [0.85,0.85,0.85,1], [0.75,0.75,0.75,1]] self.backgroundColor = [0.75,0.75,0.75,1] pyglet.gl.glClearColor(*self.backgroundColor) self.batch = pyglet.graphics.Batch() self.beta = (pi*5.)/180. self.alpha = (pi*5.)/180. self.dalpha = (pi*5.)/180. self.cameraEyesInit = np.array([4.,0.,0.]) self.cameraLookAtInit = np.array([0.,0.,0.]) self.cameraEyes = np.copy(self.cameraEyesInit) self.cameraLookAt = np.copy(self.cameraLookAtInit) self.normal = np.array([0.,0.,0.]) #self.viewUp = np.array([-0.70710678 , 0., 0.70710678]) # 45 degree self.viewUp = np.array([0 , 0., 1]) self.axisX = np.array([1.,0.,0]) self.axisY = np.array([0.,1.,0]) self.axisZ = np.array([0.,0.,1]) self.viewZoomingSensitivity = 0.5 self.viewTranslateSensitivityX = 0.001 self.viewTranslateSensitivityY = 0.0005 self.viewRotationSensitivityZ = self.dalpha ### # simulation runtime variables self.simulationRunning = False self.clock = pyglet.clock.get_default() self.updateTime = 1./60. # One-time GL setup glColor3f(1, 0, 0) glEnable(GL_DEPTH_TEST) ## uncomment this line for viewing only front faces #glEnable(GL_CULL_FACE) # Uncomment this line for a wireframe view #glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) # Simple light setup. On Windows GL_LIGHT0 is enabled by default, # but this is not the case on Linux or Mac, so remember to always # include it. glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_LIGHT1) # Define a simple function to create ctypes arrays of floats: def vec(*args): return (GLfloat * len(args))(*args) glLightfv(GL_LIGHT0, GL_POSITION, vec(.5, .5, 1, 0)) glLightfv(GL_LIGHT0, GL_SPECULAR, vec(.5, .5, 1, 1)) glLightfv(GL_LIGHT0, GL_DIFFUSE, vec(1, 1, 1, 1)) glLightfv(GL_LIGHT1, GL_POSITION, vec(1, 0, .5, 0)) glLightfv(GL_LIGHT1, GL_DIFFUSE, vec(.5, .5, .5, 1)) glLightfv(GL_LIGHT1, GL_SPECULAR, vec(1, 1, 1, 1)) ### # control GUI window self.controlWindow = ControlWindow(self) # register button events # simulation speed self.controlWindow.onPressRealTimeSim = self.visualisationSpeedRealTime self.controlWindow.onPressHalfTimeSim = self.visualisationSpeedHalfTime self.controlWindow.onChangeSpeedSlider = self.setVisualisationSpeed # view self.controlWindow.onPressViewXY = self.setViewXY self.controlWindow.onPressViewYZ = self.setViewYZ self.controlWindow.onPressViewXZ = self.setViewXZ self.controlWindow.onPressViewXYZ = self.setViewXYZ # play pause / reset self.controlWindow.onPressPlayPause = self.startVisualisation self.controlWindow.onPressReset = self.resetVisualisationAndPause # create movie self.controlWindow.onPressMovie = self.recordMovie self.controlWindow.onPressViewPhoto = self.saveScreenShot # LUT self.controlWindow.onPressLookUpTable = self.changeColorTable self.controlWindow.onPressChangeQuantity = self.changeQuantityLUT # wave split self.controlWindow.onPressSplit = self.enableWaveSplitLookUp self.controlWindow.onPressSplitExp = self.enableLeftRightColoring # vessel area/wall movement self.controlWindow.onPressWallMovement = self.enableWallMovement self.controlWindow.onChangeWallSlider = self.setAreaFactor self.controlWindow.onPressBackgroundColor = self.changeBackgroundColor def on_resize(self,width, height): self.switch_to() glViewport(0, 0, width, height) self.camera() return pyglet.event.EVENT_HANDLED def on_draw(self): self.switch_to() self.clear() # == glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) pyglet.gl.glClearColor(*self.backgroundColor) self.camera() #self.drawPlane() #self.drawCoordinateSystem() glEnable(GL_COLOR_MATERIAL) self.batch.draw() return pyglet.event.EVENT_HANDLED def resizeWindow(self,dx,dy): print "new size", self.width+dx, self.height-dy self.set_size(self.width+dx, self.height-dy) def drawPlane(self): self.planeZ = -0.25 xWidth = 1 yWidth = 1 glBegin(GL_QUADS) glColor3f(0.8,0.8,0.8) glVertex3f(xWidth,yWidth,self.planeZ) glNormal3f(0, 0, abs(self.planeZ/self.planeZ)) glVertex3f(xWidth, -yWidth,self.planeZ) glNormal3f(0, 0, abs(self.planeZ/self.planeZ)) glVertex3f(-xWidth, -yWidth,self.planeZ) glNormal3f(0, 0, abs(self.planeZ/self.planeZ)) glVertex3f(-xWidth, yWidth,self.planeZ) glNormal3f(0, 0, abs(self.planeZ/self.planeZ)) glEnd() def drawCoordinateSystem(self): glClear(GL_COLOR_BUFFER_BIT) glBegin( GL_LINES ) glColor3f( 1, 0, 0 ) glVertex3f( 0, 0, 0 ) glVertex3f( 0.1, 0, 0 ) glEnd( ) glBegin( GL_LINES ) glColor3f(0,1,0) glVertex3f( 0, 0, 0 ) glVertex3f( 0, 0.1, 0 ) glEnd( ) glBegin( GL_LINES ) glColor3f(0,0,1) glVertex3f( 0, 0, 0 ) glVertex3f( 0, 0, 0.1 ) glEnd( ) glFlush() def camera(self): glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(5,1,1,1000) glMatrixMode(GL_MODELVIEW) glLoadIdentity() gluLookAt(self.cameraEyes[0],self.cameraEyes[1],self.cameraEyes[2], self.cameraLookAt[0],self.cameraLookAt[1],self.cameraLookAt[2], self.viewUp[0],self.viewUp[1],self.viewUp[2]) def cameraTranslateZ(self,dx,dy): """ click left mouse and move 3D vessel around """ kz = -dy*self.viewTranslateSensitivityY self.cameraEyes += self.axisZ*kz self.cameraLookAt += self.axisZ*kz def cameraTranslateXY(self,dx,dy): """ click right mouse and move vessel up and down """ ky = dy*self.viewTranslateSensitivityY kx = dx*self.viewTranslateSensitivityX if self.cameraEyes[2]<0: ky = -ky if (self.cameraEyes[0:2] == self.cameraLookAt[0:2]).all(): translation = - ky* self.axisX + kx*self.axisY else: eyesLookAtVector = (self.cameraEyes-self.cameraLookAt)*(self.axisX+self.axisY) normal = np.cross(eyesLookAtVector,self.axisZ) normal = normal/np.linalg.norm(normal) translation = kx*normal + ky*eyesLookAtVector self.cameraEyes = self.cameraEyes + translation self.cameraLookAt = self.cameraLookAt + translation def zoomInAndOut(self,dx,dy): """ click middle mouse and zoom in and out """ eyesLookAtVector = self.cameraLookAt-self.cameraEyes normLE = np.linalg.norm(eyesLookAtVector) ## zooming out if dx < dy : self.cameraEyes -= self.viewZoomingSensitivity*eyesLookAtVector/normLE ## zooming in elif dx > dy: if normLE > 2: self.cameraEyes += self.viewZoomingSensitivity*eyesLookAtVector/normLE def rotate(self,dx,dy): """ click right and left mouse to rotate around the z axis and the axis normal to the view plane """ eyesLookAtVector = self.cameraEyes-self.cameraLookAt # EL #print 'eyesLookAtVector', eyesLookAtVector eyesLookAtVectorProjection = eyesLookAtVector*np.array([1.,1.,0.]) #ELxy n = np.dot(eyesLookAtVectorProjection,eyesLookAtVector) normEyesLookAtVector = np.linalg.norm(eyesLookAtVector) normEyesLookAtVectorProjection = np.linalg.norm(eyesLookAtVectorProjection) normProduct = normEyesLookAtVector*normEyesLookAtVectorProjection if normProduct == 0: normProduct = 1 cosAlpha = (n/normProduct) if cosAlpha > 1 : cosAlpha = 1.0 elif cosAlpha < -1 : cosAlpha = -1.0 alpha = np.int(np.floor(np.arccos(cosAlpha)/np.pi*180.)) degreeFactor = 180/pi radianFactor = pi/180 if alpha < 1.: # <---------------------------------------------------------CASE 1 self.viewUp= np.array([0,0,1]) if abs(dx) > 2: self.cameraRotateAroundZ(dx) if abs(dy) > 1: self.cameraRotateGear(dy) elif alpha >= 89.:#<--------------------------------------------------------CASE 2 if abs(dy) > 1: self.cameraRotateGear(dy) if abs(dx) > 2: self.cameraRotateAroundZ(dx, rotateViewUp = True) else: #<----------------------------------------------------------------------CASE 3 # rotate n = np.cross(eyesLookAtVectorProjection,eyesLookAtVector) viewUp = np.cross(n,eyesLookAtVector) viewUpNorm = np.linalg.norm(viewUp) if self.cameraEyes[2] > self.cameraLookAt[2]: self.viewUp = viewUp/viewUpNorm else: self.viewUp = - viewUp/viewUpNorm if abs(dx) > 2: self.cameraRotateAroundZ(dx) if abs(dy) > 1: self.cameraRotateGear(dy) def cameraRotateAroundZ(self, dx, rotateViewUp = False): signDx = -dx/abs(dx) Rz = np.array( [[cos(self.alpha), signDx*sin(self.alpha), 0.], [-signDx*sin(self.alpha), cos(self.alpha), 0.], [0., 0., 1.]]) if rotateViewUp == False: self.cameraEyes = np.dot(self.cameraEyes,Rz) else: self.viewUp = np.dot(self.viewUp,Rz) def cameraRotateGear(self,dy): ## if mouse moves horizontaly s = dy/abs(dy) #E = np.array( [self.EX,self.EY,0] ) E = self.cameraEyes*(self.axisX+self.axisY) self.normal = np.cross(self.axisZ,E) # normal to plane (z,E) lengthN = np.linalg.norm(self.normal) ux, uy, uz = -self.normal[0]/lengthN, -self.normal[1]/lengthN, -self.normal[2]/lengthN # normalize normal coordinates #if n == 0: A11 = cos(self.beta)+ux*ux*(1-cos(self.beta)) A12 = ux*uy*(1-cos(self.beta))-uz*sin(self.beta) A13 = ux*uz*(1-cos(self.beta))+uy*sin(self.beta) A21 = uy*ux*(1-cos(self.beta))+uz*sin(self.beta) A22 = cos(self.beta)+uy*uy*(1-cos(self.beta)) A23 = uy*uz*(1-cos(self.beta))-ux*sin(self.beta) A31 = uz*ux*(1-cos(self.beta))-uy*sin(self.beta) A32 = uz*uy*(1-cos(self.beta))+ux*sin(self.beta) A33 = cos(self.beta)+uz*uz*(1-cos(self.beta)) Rn = np.array( [[A11, A12, A13], [A21, A22, A23], [A31, A32, A33]] ) if s < 0: self.cameraEyes = np.dot(self.cameraEyes,Rn) # upwards rotation elif s > 0: self.cameraEyes = np.dot(Rn,self.cameraEyes.T).T #downwards # def on_mouse_drag(self,x,y,dx,dy,buttons,modifiers): if buttons == 1: # left mouse button if self.keys[key.LCTRL] == False: self.cameraTranslateXY(dx,dy) else: self.resizeWindow(dx, dy) elif buttons == 4: # right mouse button self.cameraTranslateZ(dx,-dy) elif buttons == 5: # left plus right self.rotate(dx,dy) elif buttons == 2: # middle button to zoo self.zoomInAndOut(dx,dy) def on_mouse_scroll(self, x, y, scroll_x, scroll_y): self.zoomInAndOut(0,-scroll_y) def on_key_press(self,symbol, modifiers): #### start stop simulation visualisation if symbol == key.P: self.startVisualisation() elif symbol == key.O: self.resetVisualisationAndPause() #### visualisation speed elif symbol == key.H: self.visualisationSpeedHalfTime() elif symbol == key.R: self.visualisationSpeedRealTime() elif symbol == key.PLUS: self.visualisationSpeedUp() elif symbol == key.MINUS: self.visualisationSpeedDown() #### look up table stuff elif symbol == key.L: self.changeColorTable() elif symbol == key.W: self.enableWaveSplitLookUp() elif symbol == key.E: self.enableLeftRightColoring() elif symbol == key.Q: self.changeQuantityLUT() elif symbol == key.A: self.enableWallMovement() ### create movie: elif symbol == key.M: self.recordMovie() elif symbol == key.S: self.saveScreenShot() elif symbol == pyglet.window.key.ESCAPE: self.on_close() elif symbol == key.B: self.changeBackgroundColor() ## view elif symbol == key._1 : self.setViewXY() elif symbol == key._2 : self.setViewYZ() elif symbol == key._3 : self.setViewXZ() elif symbol == key._4 : self.setViewXYZ()() elif symbol == key.NUM_8: # rotate up wards self.rotate(0,2) elif symbol == key.NUM_2: # rotate downwards self.rotate(0,-2) elif symbol == key.NUM_6: # rotate right self.rotate(4,0) elif symbol == key.NUM_4: # rotate left self.rotate(-4,0) def on_close(self): self.cLUT.windowLUT.switch_to() pyglet.app.exit() self.controlWindow.switch_to() pyglet.app.exit() self.switch_to() pyglet.app.exit() ### callback functions def startVisualisation(self): if self.simulationRunning: #stop it self.clock.unschedule(self.updateVisualisation) self.simulationRunning = False else: #start it self.clock.schedule_interval(self.updateVisualisation,self.updateTime) # self.simulationRunning = True def resetVisualisationAndPause(self): if self.simulationRunning : self.startVisualisation() self.timeStepCurrent = 0 self.updateVisualisation(self.updateTime) self.timeStepCurrent = 0 self.switch_to() self.on_draw() def updateVisualisation(self,dt): pass ## visualisation speed def visualisationSpeedHalfTime(self): pass def visualisationSpeedRealTime(self): pass def visualisationSpeedUp(self): pass def visualisationSpeedDown(self): pass def setVisualisationSpeed(self, value): pass def changeColorTable(self): pass ### area / vessel wall def enableWallMovement(self): pass def setAreaFactor(self): pass ### wave split def enableWaveSplitLookUp(self): pass def enableLeftRightColoring(self): pass def changeQuantityLUT(self): pass ### record save movie screenshot def recordMovie(self): pass def saveScreenShot(self): pass ### def changeBackgroundColor(self): tableIterator = range(len(self.backgroundColors)) tableIterator.pop(0) tableIterator.append(0) self.backgroundColor = self.backgroundColors[self.backgroundColorIterator] self.backgroundColorIterator = tableIterator[self.backgroundColorIterator] ### view def setViewXY(self): self.cameraEyes = np.array([0.,0.,4.]) self.cameraLookAt = np.array([0.,0.,0.]) self.viewUp = np.array([1.,0.,0.]) def setViewYZ(self): self.cameraEyes = np.array([4.,0.,0.]) self.cameraLookAt = np.array([0.,0.,0.]) self.viewUp = np.array([0.,0.,1.]) def setViewXZ(self): self.cameraEyes = np.array([0.,-4.,0.]) self.cameraLookAt = np.array([0.,0.,0.]) self.viewUp = np.array([0.,0.,1.]) def setViewXYZ(self): self.cameraEyes = np.copy(self.cameraEyesInit) self.cameraLookAt = np.copy(self.cameraLookAtInit) self.viewUp = np.array([0.,0.,1.])