""" qtgui/MGGLWidget.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC Copyright (C) 2009-2011 University of York Copyright (C) 2012 STFC This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ """PyQt4 port of the opengl/hellogl example from Qt v4.x""" import sys import os import time import types import math import operator from PyQt4 import QtCore, QtGui, QtOpenGL, QtSvg import sip from global_definitions import PM, MAINWINDOW, get_dispobj import MGPickEvent import opengl from MGGLWidgetCore import MGGLWidgetCore, MGGLWidgetSimple, MGGLWidgetGL try: import opengl import pygl_coord import cprim import surface import image_info except ImportError: exc_type, exc_value,exc_tb = sys.exc_info()[:3] if str(exc_value).find('cannot restore segment prot after reloc')>-1: fixperms = os.path.join(os.path.normpath(os.environ["CCP4MG"]),"bin","fix-selinux-perms") QtGui.QMessageBox.critical(None, "Failed to import some ccp4mg libraries", "SELINUX stoppped ccp4mg working.\nPlease run the script\n"+fixperms+"\nto fix this problem.", QtGui.QMessageBox.Ok ) else: exc_type, exc_value,exc_tb = sys.exc_info()[:3] QtGui.QMessageBox.critical(None, "Failed to import some ccp4mg libraries", "There was a problem with some of the program libraries. Please report this as a bug to ccp4mg@ysbl.york.ac.uk.", QtGui.QMessageBox.Ok ) sys.stderr.write(str(exc_type)+'\n') sys.stderr.write(str(exc_value)+'\n') import traceback traceback.print_tb(exc_tb) sys.exit(1) def getMaxSampleBuffersFormat(start=16): numSampleBuffers=start haveSampleBuffers = False fmt = QtOpenGL.QGLFormat() fmt.setRgba (1); fmt.setDepth (1); fmt.setAlpha (1); fmt.setStencil(True) if sys.platform != "linux2": fmt.setSwapInterval(1) fmt.setSampleBuffers (True); return fmt def applyMiscPrefs(): try: params = PM("miscell_prefs").getparams() app = QtGui.QApplication.instance() if params.has_key('flip_text'): app.setProperty("flip_labels",params['flip_text']) for dispobj in get_dispobj(): dispobj.set_redraw_text() import rebuild rebuild.UpdateDisplay() except: print "Error getting micellaneous options" def applyAOPrefs(): import MGApplication try: params = PM("ambient_occlusion_prefs").getparams() mainwin = MGApplication.GetMainWindow() mainwin.glWidget.setAmbientOcclusionPrefs(params) except: print "Error getting SSAO options" def createAOParamsManager(): import services pm = services.ParamsManager ( name="ambient_occlusion_prefs", title="Ambient occlusion options", help="_has_no_help_", gui=['ambocc_znear','ambocc_zfar','ambocc_radius','ambocc_scale','ambocc_bias'], apply_action = applyAOPrefs, default = { 'ambocc_znear' : 100.0, 'ambocc_zfar' : 150.0, 'ambocc_radius': 15.0, 'ambocc_bias' : 0.3, 'ambocc_scale' : 1.0 }, definition = { "ambocc_znear" : dict(type=float, min=0,max=600, label='Ambient occlusion Near eye', style='spinbox' ), "ambocc_zfar" : dict(type=float, min=0,max=600, label='Ambient occlusion Far eye', style='spinbox' ), "ambocc_radius" : dict(type=float, min=0,max=150, label='Ambient occlusion radius', style='spinbox' ), "ambocc_bias" : dict(type=float, min=0.0,max=1.0,step=0.1, label='Ambient occlusion bias', style='spinbox' ), "ambocc_scale" : dict(type=float, min=0.0,max=1.0,step=0.1, label='Ambient occlusion scale', style='spinbox' ) } ) return pm def createMiscParamsManager(): import services pm = services.ParamsManager ( \ name="miscell_prefs", title='Miscellaneous graphics options', \ help="_has_no_help_", c_access= 1, apply_action = applyMiscPrefs, gui=['text_label_background','text_label_background_colour','fog_text','depth_text','flip_text'], \ default = { 'depth_text':0, 'fog_text':0, 'text_label_background' : 0, 'flip_text' : 0, 'text_label_background_colour':'white' }, definition = { 'text_label_background_colour' : dict(type=str, label='Text label background colour',style='colourcombo'), 'text_label_background' : dict(type=int,label='Text labels have background', style='checkbox'), 'fog_text' : dict(type=int,label='Apply depth-cue fog to text labels', style='checkbox'), 'depth_text' : dict(type=int,label='Text labels can disappear behind objects', style='checkbox'), 'flip_text' : dict(type=int,label='Invert text display', style='checkbox'), }) return pm #--------------------------------------------------------------------------------- def createStereoParamsManager(): #--------------------------------------------------------------------------------- import services import MGApplication def onChange(pmg): stereoModeWidget = pmg.findChild(QtGui.QWidget,'stereo_mode') shearSepWidget = pmg.findChild(QtGui.QWidget,'shear_sep') rotSepWidget = pmg.findChild(QtGui.QWidget,'rot_sep') if not stereoModeWidget or not shearSepWidget or not rotSepWidget: return if not hasattr(stereoModeWidget,"currentText") or not hasattr(shearSepWidget,"setEnabled") or not hasattr(rotSepWidget,"setEnabled"): return if stereoModeWidget.currentText() == stereoModeWidget.tr("Rotation"): shearSepWidget.setEnabled(False) rotSepWidget.setEnabled(True) else: shearSepWidget.setEnabled(True) rotSepWidget.setEnabled(False) pm = services.ParamsManager ( \ name="stereo_prefs", picture_definition = 1, title='Stereo preferences', \ help="_has_no_help_", onCreate=onChange, \ c_access= 1, apply_action = MGApplication.GetMainWindow().applyStereoPrefs, gui=['stereo_mode', 'shear_sep', 'rot_sep'], \ default = { 'stereo_mode' : 1, 'shear_sep' : 0.1, 'rot_sep': 6.0 }, definition = { 'stereo_mode' : dict(type=int,label='Stereo mode', style='combobox',menu=['Shear','Rotation'],alias=[0,1],onchange=onChange), 'shear_sep' : dict(type='float',label='Shear separation',max=5.0,min=-5.0,step=0.05,style='spinbox'), 'rot_sep' : dict(type='float',label='Rotation angle',max=10.0,min=-10.0,step=0.05,style='spinbox') }) return pm class KeyPressEater(QtCore.QObject): def __init__(self,parent=None): QtCore.QObject. __init__(self,parent) def eventFilter(self,pObject,pEvent): if pEvent.type() == QtCore.QEvent.KeyPress: return True else: return QtCore.QObject.eventFilter(self,pObject, pEvent); class MGGLWidget(QtOpenGL.QGLWidget,MGGLWidgetGL): def enterEvent(self,e): QtOpenGL.QGLWidget.enterEvent(self,e) self.setFocus() self.emit(QtCore.SIGNAL("MouseEntered"),(self)) def updateGL(self): QtOpenGL.QGLWidget.updateGL(self) def makeCurrent(self): QtOpenGL.QGLWidget.makeCurrent(self) """ def event(self,e): if QtCore.QT_VERSION >= 0x40600 and QtCore.PYQT_VERSION >= 0x040700 and sip.SIP_VERSION >= 0x040a00 and e.type() == QtCore.QEvent.Gesture: if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,0) if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,0) return self.gestureEvent(e) return QtOpenGL.QGLWidget.event(self,e) def gestureEvent(self,e): if QtCore.QT_VERSION < 0x40600 or QtCore.PYQT_VERSION < 0x040700 or sip.SIP_VERSION < 0x040a00: return pinch = e.gesture(QtCore.Qt.PinchGesture) swipe = e.gesture(QtCore.Qt.SwipeGesture) pan = e.gesture(QtCore.Qt.PanGesture) if swipe: #print "Swipe" pass if pan: #print "Pan" pass if pinch: self.handleZoom(e,0,50*(pinch.scaleFactor()-pinch.lastScaleFactor())) self.setRotation(0,0,-(pinch.rotationAngle()-pinch.lastRotationAngle())) return True """ def setBackground(self,r,g,b,a=255): self.bgcolour = QtGui.QColor(r,g,b,a) self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() self.qglClearColor(self.bgcolour) self.updateGL() cprim.RGBReps().SetBackgroundColour([r/255.,g/255.,b/255.,a/255.]) def centreOn(self,origin,glide=1): import functools #print "%_%_%_%_%_%_%_%_%_%_%_%_%_%_%_centreOn",origin #if glide<0: glide = PM('user_interface').get('camera_glide') rpos_old = self.rpos rpos_new = (-origin[0],-origin[1],-origin[2]) if glide: self.glide_initial_time = time.time() if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,0) if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,0) def glide_handler(rpos_old,rpos_new): elapsed = time.time() - self.glide_initial_time fi = min(1.0,elapsed) fip = 1.0 - fi rpos_cur = [fip*rpos_old[0]+fi*rpos_new[0],fip*rpos_old[1]+fi*rpos_new[1],fip*rpos_old[2]+fi*rpos_new[2]] self.rpos = rpos_cur self.emit(QtCore.SIGNAL("PositionChanged"),(self)) self.SetupSymmetry() self.updateGL() if elapsed >= 1.0: if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,2) if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,2) self.glide_timer.stop() if hasattr(self,"glide_timer"): self.glide_timer.stop() self.glide_timer = QtCore.QTimer(self) self.connect(self.glide_timer,QtCore.SIGNAL('timeout()'),functools.partial(glide_handler,rpos_old,rpos_new)) self.glide_timer.start() self.emit(QtCore.SIGNAL("ViewChanged"),(self)) else: self.rpos = rpos_new self.emit(QtCore.SIGNAL("PositionChanged"),(self)) self.SetupSymmetry() self.updateGL() self.emit(QtCore.SIGNAL("ViewChanged"),(self)) def DrawAxes(self): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() if not self.show_axes: return MGGLWidgetGL.DrawAxes(self) def DrawScale(self): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() if not self.show_scale: return MGGLWidgetGL.DrawScale(self) def getBackgroundAlpha(self): return self.bgcolour.alpha() def screenshot_pbuffer_new(self,size=QtCore.QSize(600,600),scalebartext=True,scaleLines=False,old_w=-1): import time t1 = time.time() fbo_height = 1024 fbo_width = 1024 self.fbo_offset = 512 if old_w == -1: print "!!!!!!!!!!!!!! SETTING OLD_W !!!!!!!!!!!!!!!!!!!!",self.width() old_w = int(1.0*self.width()) if not hasattr(self,"pbuffer"): fmt = QtOpenGL.QGLFramebufferObjectFormat() if self.format().samples() > 1: fmt.setSamples(self.format().samples()) fmt.setAttachment(QtOpenGL.QGLFramebufferObject.Depth) self.pbuffer = QtOpenGL.QGLFramebufferObject(QtCore.QSize(fbo_height+2*self.fbo_offset,fbo_width+2*self.fbo_offset),fmt) print self.pbuffer.size(),self.pbuffer.format().samples(),self.pbuffer.isValid() self.BindOffScreenBuffer = self.BindOffScreenBufferFBO radius = self.RADIUS if fbo_height < size.height() or fbo_width < size.width(): ntiles_x = (size.width()+fbo_width-1)/fbo_width ntiles_y = (size.height()+fbo_height-1)/fbo_height req_size = QtCore.QSize(ntiles_x*fbo_width,ntiles_y*fbo_height) self.RADIUS = float(req_size.height())/size.height()*self.RADIUS #self.RADIUS = float(self.pbuffer.height())/req_size.height()*self.RADIUS #self.resize(self.pbuffer.width(),self.pbuffer.height()) self.RADIUS = float(2048)/req_size.height()*self.RADIUS print self.RADIUS self.resize(2048,2048) else: req_size = size self.resize(req_size.width(),req_size.height()) self.req_pbuffer_size = req_size self.use_pbuffer = True if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,2) if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,2) self.BindOffScreenBuffer() self.drawText = False import global_definitions misco = global_definitions.PM('miscell_prefs') depth_text = misco.get('depth_text') doText=True if depth_text: print "Not doing separate text, because of text depth. But should be scaled",self.fontScaling self.drawText = True doText=False self.drawImages = False self.use_pbuffer = True self.rebuildAllDisplayObjects(redraw=0) self.use_pbuffer = True self.BindOffScreenBuffer() rpos = self.rpos show_axes = self.show_axes show_scale = self.show_scale # Loop here for tiling self.updateGL() theScaling = 1.0 print fbo_height, size.height(), fbo_width, size.width() if fbo_height >= size.height() and fbo_width >= size.width(): self.axes_mag = 1.0 if scaleLines: self.line_scaling = size.width()/float(old_w) print "LINE SCALING",self.line_scaling else: self.line_scaling = 1.0 self.show_axes = False self.show_scale = False self.axes_position = (0.75,0.75) self.updateGL() image = self.pbuffer.toImage().copy(0,fbo_height-size.height()+2*self.fbo_offset,size.width(),size.height()) self.updateGL() self.show_axes = show_axes self.show_scale = show_scale #self.line_scaling = fbo_width/float(old_w) else: # This works for 2048x2048, 4096x4096, 2048x4096, 4096x2048, 8192x8192, 8192x4096, 8192x1024 # and n x screen size and dpi it seems. Not worked out max feasible size yet.... self.show_axes = False self.show_scale = False theScaling = 1.0*size.height()/self.height() pix = QtGui.QPixmap(ntiles_x*fbo_width, ntiles_y*fbo_height) pix.fill(QtGui.QColor(0,0,0,0)) self.axes_position = (-(ntiles_x-2.0)/ntiles_x-.25/ntiles_x,-(ntiles_y-2.0)/ntiles_y-.25/ntiles_y) self.axes_mag = max(float(size.height())/fbo_height , float(size.height())/fbo_height) if scaleLines: self.line_scaling = size.width()/float(old_w) print "LINE SCALING",self.line_scaling,"(",size.width(),",",old_w,")" else: self.line_scaling = 1.0 customClipPlanes = self.customClipPlanes painter = QtGui.QPainter(pix) for i in range(ntiles_x): for j in range(ntiles_y): if False and ntiles_y == 1: diffCart = pygl_coord.Cartesian((-i+(float(self.fbo_offset)/fbo_width)+0.25+0.5*(ntiles_x-2))*self.viewsize*self.RADIUS/60.*2048./self.height(),0.25,0) elif False and ntiles_x == 1: diffCart = pygl_coord.Cartesian(0.25,(-j+(float(self.fbo_offset)/fbo_height)+0.25+0.5*(ntiles_y-2))*self.viewsize*self.RADIUS/60.*2048./self.height(),0) else: diffCart = pygl_coord.Cartesian((-i+(float(self.fbo_offset)/fbo_width)+0.5*(ntiles_x-2))*self.viewsize*self.RADIUS/60.*2048./self.height(),(-j+(float(self.fbo_offset)/fbo_height)+0.5*(ntiles_y-2))*self.viewsize*self.RADIUS/60.*2048./self.height(),0) planesNew = [] for pl in customClipPlanes: if hasattr(pl,"has_key") and pl.has_key("visible") and pl.has_key("plane") and len(pl["plane"])==4: thePlane = pl["plane"] pl_b = pygl_coord.Cartesian(-thePlane[0],-thePlane[1],thePlane[2]) a1 = 0.0 if pl_b.length()>0.0: pl_b.normalize() a1 = pygl_coord.Cartesian.DotProduct(diffCart,pl_b) newPlane = {} newPlane["visible"] = pl["visible"] newPlane["plane"] = (thePlane[0],thePlane[1],thePlane[2],thePlane[3]+a1) planesNew.append(newPlane) self.setCustomClipPlanes(planesNew) diffCart = self.quat.getInvMatrix()*diffCart self.rpos = (rpos[0]+diffCart.get_x(),rpos[1]+diffCart.get_y(),rpos[2]+diffCart.get_z()) self.updateGL() #self.pbuffer.toImage().save("fbo-"+str(i)+"-"+str(j)+".png") image = self.pbuffer.toImage().copy(self.fbo_offset,self.fbo_offset,fbo_width,fbo_height) painter.drawImage(i*fbo_width,(ntiles_y-j-1)*fbo_height,image) print "time for image",i,j,time.time()-t1; sys.stdout.flush() painter.end() #image = pix.toImage().copy(0,ntiles_y*fbo_height-size.height(),size.width(),size.height()) image = pix.toImage().copy((req_size.width()-size.width())/2,ntiles_y*fbo_height-size.height()-(req_size.height()-size.height())/2,size.width(),size.height()) print "time for accumulated image",time.time()-t1; sys.stdout.flush() self.show_axes = show_axes self.show_scale = show_scale self.axes_position = (0.75,0.75) self.customClipPlanes = customClipPlanes self.RADIUS = radius # end loop here and accumulate images. self.rpos = rpos self.applyTextPBuffer(image,doText=doText,theScaling=theScaling,scalebartext=scalebartext) print "time for text and overlays",time.time()-t1; sys.stdout.flush() self.axes_mag = None self.line_scaling = 1.0 self.drawText = True self.drawImages = True self.pbuffer.release() self.use_pbuffer = False print "time for release",time.time()-t1; sys.stdout.flush() #self.resize(size.width(),size.height()) return image def screenshot_pbuffer(self,size=QtCore.QSize(600,600),scalebartext=True,scaleLines=False,old_w=-1): return self.screenshot_pbuffer_new(size,scalebartext,scaleLines,old_w) def screenshot_pbuffer_old(self,size=QtCore.QSize(600,600)): debug = False if os.environ.has_key("CCP4MG_DEBUG_PBUFFER"): debug = True if debug: t1 = time.time() r,g,b = self.getBackground() a = self.getBackgroundAlpha() if not hasattr(self,"pbuffer_glWidget"): self.pbuffer_glWidget = MGGLWidget(MAINWINDOW(),self,format=self.format(),use_pbuffer=True,pbuffer_size=QtCore.QSize(2048,2048)) if debug: t2 = time.time() if debug: print "Time for pbuffer construct widget",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.req_pbuffer_size = size self.pbuffer_glWidget.drawTextSeparately = True if hasattr(self,"pbuffer_glWidget"): rp,gp,bp = self.pbuffer_glWidget.getBackground() ap = self.pbuffer_glWidget.getBackgroundAlpha() if a != ap or r != rp or g != gp or b != bp: self.pbuffer_glWidget.setBackground(r,g,b,a) if debug: t2 = time.time() if debug: print "Time for pbuffer set bg",t2-t1; sys.stdout.flush() for item in ['RADIUS','quat','fog_enabled','fog_strength','fog_near','fog_far','slab_enabled','slab_width','slab_offset']: setattr(self.pbuffer_glWidget,item,getattr(self,item)) if debug: t2 = time.time() if debug: print "Time for pbuffer setattr",t2-t1; sys.stdout.flush() if debug: print size, self.pbuffer_glWidget.size() if size.width()!=self.pbuffer_glWidget.width() or size.height()!=self.pbuffer_glWidget.height(): self.pbuffer_glWidget.resizeGL(size.width(),size.height()) if debug: t2 = time.time() if debug: print "Time for pbuffer resize",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.setExtraMatrix(None) if debug: t2 = time.time() if debug: print "Time for pbuffer set extra matrix",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.setLights(MAINWINDOW().lights) if debug: t2 = time.time() if debug: print "Time for pbuffer set lights",t2-t1; sys.stdout.flush() shaders = self.getShader() self.pbuffer_glWidget.setShader(shaders[0],shaders[1]) self.pbuffer_glWidget.setShaderState(self.getShaderState()) if debug: t2 = time.time() if debug: print "Time for pbuffer set shaders",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.updateGL() if debug: t2 = time.time() if debug: print "Time for pbuffer draw 1",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.drawText = False self.pbuffer_glWidget.drawImages = False if self.go: self.pbuffer_glWidget.SetGO(self.go,1) if debug: t2 = time.time() if debug: print "Time for pbuffer set objects",t2-t1; sys.stdout.flush() cprim.RenderQuality.SetRenderQuality(1) if debug: t2 = time.time() if debug: print "Time for pbuffer SetRenderQuality",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.rebuildAllDisplayObjects(redraw=0) if debug: t2 = time.time() if debug: print "Time for pbuffer rebuildAllDisplayObjects",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.SetOrigin(self.rpos,0) if debug: t2 = time.time() if debug: print "Time for pbuffer SetOrigin",t2-t1; sys.stdout.flush() self.pbuffer_glWidget.drawText = False self.pbuffer_glWidget.drawImages = False self.pbuffer_glWidget.updateGL() if debug: t2 = time.time() if debug: print "Time for pbuffer draw 2",t2-t1; sys.stdout.flush() image = self.pbuffer_glWidget.pbuffer.toImage().copy((2048-size.width())/2,(2048-size.height())/2,size.width(),size.height()) self.resizeGL(size.width(),size.height()) self.updateGL() self.applyTextPBuffer(image) if debug: t2 = time.time() if debug: print "Time for pbuffer convert to image",t2-t1; sys.stdout.flush() #self.pbuffer_glWidget.close() if debug: t2 = time.time() if debug: print "Time for pbuffer all",t2-t1; sys.stdout.flush() cprim.RenderQuality.SetRenderQuality(0) return image def applyTextPBuffer(self,image,doText=True,theScaling=1.0,scalebartext=True): debug = False if os.environ.has_key("CCP4MG_DEBUG_MEMORY"): debug = True width = image.width() height = image.height() theImage = image i = 0 if self.bgcolour.alpha() == 0 and self.bgcolour.red() == 0 and self.bgcolour.green() == 0 and self.bgcolour.blue() == 0 and self.fogcolour.alpha() != 0 and self.fogcolour.red() != 0 and self.fogcolour.green() != 0 and self.fogcolour.blue() != 0: bright_y = self.fogcolour.redF()*0.299 + self.fogcolour.greenF()*0.587 + self.fogcolour.blueF()*0.114; else: bright_y = self.bgcolour.redF()*0.299 + self.bgcolour.greenF()*0.587 + self.bgcolour.blueF()*0.114; quat = pygl_coord.Quat(self.quat) quat.postMult(self.extra_quat) viewport = pygl_coord.inta(4) opengl.glGetIntegerv(opengl.GL_VIEWPORT,viewport); tl = opengl.getxyzc(viewport[0],viewport[1])[0]; bl = opengl.getxyzc(viewport[0],viewport[3])[0]; yscale = (tl-bl).length()*theScaling scale = yscale print scale import FontedPositionedStrings painter = QtGui.QPainter() painter.begin(image) images = [] for go in self.go: if go.obj.visible>0: prims = go.obj.GetImagePrimitives() for prim in prims: if debug: print prim verts = prim.GetVertices() imageWidth = prim.GetImageWidth() imageHeight = prim.GetImageHeight() scale_w = prim.GetScaleW()*self.fontScaling scale_h = prim.GetScaleH()*self.fontScaling filename = prim.GetFilename() isSvg = False if filename[-3:] == "svg" and len(verts) > 0 : try: v0 = verts[0] svg = QtSvg.QSvgRenderer(unicode(filename,'utf-8')) if svg.isValid(): x1 = v0.get_x()*painter.device().width() y1 = painter.device().height()*(1.0-v0.get_y())-svg.defaultSize().height()*scale_h bounds = QtCore.QRectF(x1,y1,svg.defaultSize().width()*scale_w,svg.defaultSize().height()*scale_h) #svg.render(painter,bounds) image = {"filename":filename, "bounds":bounds} images.append(image) isSvg = True except: print "did not load",filename,"as svg" sys.stdout.flush() piccy = QtGui.QImage(unicode(filename,'utf-8')) piccy = piccy.scaled(int(piccy.width()*scale_w),int(piccy.height()*scale_h),QtCore.Qt.IgnoreAspectRatio,QtCore.Qt.SmoothTransformation) if not isSvg and len(verts) > 0 and not piccy.isNull() and scale_w > 0 and scale_h >0: v0 = verts[0] x = int(v0.get_x()*painter.device().width()) y = int(painter.device().height()*(1.0-v0.get_y()))-piccy.height() #painter.drawPixmap(x,y,piccy) image = {"filename":filename,"x":x,"y":y,"width":int(piccy.width()),"height":int(piccy.height())} images.append(image) if debug: print images for image in images: if hasattr(image,"has_key"): if image.has_key("bounds") and image.has_key("filename"): #print "SVG",image["filename"],image["bounds"] svg = QtSvg.QSvgRenderer(unicode(image["filename"],'utf-8')) svg.render(painter,image["bounds"]) if image.has_key("x") and image.has_key("y") and image.has_key("filename") and image.has_key("width") and image.has_key("height"): #print "bitmap",image["filename"],image["x"],image["y"],image["width"],image["height"] piccy = QtGui.QImage(unicode(image["filename"],'utf-8')) piccy = piccy.scaled(image["width"],image["height"],QtCore.Qt.IgnoreAspectRatio,QtCore.Qt.SmoothTransformation) painter.drawImage(image["x"],image["y"],piccy) import global_definitions misco = global_definitions.PM('miscell_prefs') tlb = misco.get('text_label_background') bgcol = None if tlb: text_label_background_colour = misco.get('text_label_background_colour') if text_label_background_colour: if text_label_background_colour == "default": bgcol = (self.bgcolour.redF(),self.bgcolour.greenF(),self.bgcolour.blueF()) else: bgcol = cprim.RGBReps.GetColour(text_label_background_colour.replace('_',' ')) thePrims = [] for go in self.go: if doText and go.obj.visible>0: prims = go.obj.GetTextPrimitives() for prim in prims: text,isBill,cart = prim.GetText(),prim.IsBillBoard(),prim.GetVertices()[0] cartOrig = cart if not isBill: cart = quat.getMatrix()*(cart+pygl_coord.Cartesian(self.rpos)) x,y,z = cart.get_x(),cart.get_y(),-cart.get_z() thePrims.append({'prim':prim,'z':z,'go':go,'x':x,'y':y}) symm_mat = [] if not isBill: if hasattr(go,"symmetry_dependent") and go.symmetry_dependent and go.symmetry_dependent.draw_symmetry and hasattr(go.symmetry_dependent.obj,"GetNumSymmetryMatrices"): if go.symmetry_dependent.symmetry_labels: nsym = go.symmetry_dependent.obj.GetNumSymmetryMatrices() symm_mat = pygl_coord.MatrixVector(go.symmetry_dependent.obj.symm_mat) if hasattr(go,"draw_symmetry") and go.draw_symmetry and hasattr(go.obj,"GetNumSymmetryMatrices"): nsym = go.obj.GetNumSymmetryMatrices() symm_mat = pygl_coord.MatrixVector(go.obj.symm_mat) for mat in symm_mat: cartSym = quat.getMatrix()*(mat*cartOrig+pygl_coord.Cartesian(self.rpos)) xSym,ySym,zSym = cartSym.get_x(),cartSym.get_y(),cartSym.get_z() thePrims.append({'prim':prim,'z':-zSym,'go':go,'x':xSym,'y':ySym}) thePrims = sorted(thePrims,key=operator.itemgetter('z'),reverse=True) for go in self.go: if doText and go.obj.visible>0: prims = go.obj.GetTextPrimitives() for prim in prims: text,isBill,cart = prim.GetText(),prim.IsBillBoard(),prim.GetVertices()[0] if isBill: thePrims.append({'prim':prim,'z':0,'go':go}) """ for go in self.go: if doText and go.obj.visible>0: prims = go.obj.GetTextPrimitives() for prim in prims: """ for _prim in thePrims: prim = _prim['prim'] go = _prim['go'] text,isBill,cart = prim.GetText(),prim.IsBillBoard(),prim.GetVertices()[0] cartOrig = cart font = QtGui.QFont(prim.GetFontFamily(),prim.GetFontSize()) if prim.GetFontSlant() == "o" or prim.GetFontSlant() == "i": font.setItalic(True) else: font.setItalic(False) if prim.GetFontWeight() == "bold": font.setWeight(QtGui.QFont.Bold) if prim.GetFontUnderline(): font.setUnderline(True) else: font.setUnderline(False) s = FontedPositionedStrings.FontedPositionedStringsFromText(text,fontScaling=self.fontScaling,defaultFont=font) descent = 0 fog_factor = 1.0 if isBill: xfrac,yfrac = cart.get_x(),cart.get_y() x,y = xfrac*width, height-int(yfrac*height)-1 # Cannot help think we need the same for non-billboards. descent = s.getDescent() else: cart = quat.getMatrix()*(cart+pygl_coord.Cartesian(self.rpos)) #x,y,z = cart.get_x(),cart.get_y(),-cart.get_z() x,y,z = _prim['x'],_prim['y'],_prim['z'] fog_text = misco.get('fog_text') if fog_text and self.fog_far > self.fog_near: fog_factor = 1.0 - (z - self.fog_near)/(self.fog_far - self.fog_near) fog_factor = min(fog_factor,1.0) fog_factor = max(fog_factor,0.0) xfrac,yfrac = x/scale+0.5, y/scale+0.5 x,y = int((xfrac*height)+(width-height)/2.0),height-int((yfrac*height))-1 #pixmaps = renderStringToPixmap(text) #print self.fontScaling brect = s.getBoundingRect() fog_alpha = int(255*fog_factor) if bgcol: painter.setPen(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2],fog_factor)) painter.setBrush(QtGui.QBrush(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2],fog_factor))) if isBill: painter.drawRect(x,y+descent-brect.height()*.1,brect.width(),-brect.height()) else: painter.drawRect(x,y+descent+brect.height()*.2,brect.width(),-brect.height()) if bright_y <0.5: painter.setPen(QtGui.QColor(255,255,255,fog_alpha)) else: painter.setPen(QtGui.QColor(0,0,0,fog_alpha)) FontedPositionedStrings.drawFontedPositionedStrings(s.getStrings(),painter,x,y-descent,defaultFont=font) if hasattr(self,"axes_mag") and self.axes_mag and self.show_scale: ratio = float(width) / float(height); print "Now draw scale on image" if bright_y <0.5: pen = QtGui.QPen(QtGui.QColor(255,255,255)) else: pen = QtGui.QPen(QtGui.QColor(0,0,0)) pen.setWidth(3.0*self.line_scaling) font = QtGui.QFont("Times",24*self.axes_mag) painter.setPen(pen) painter.setFont(font) print "Scale position",QtCore.QPointF(.7*width,.95*height) painter.drawLine(QtCore.QPointF(.7*width,.95*height),QtCore.QPointF(.95*width,.95*height)) painter.drawLine(QtCore.QPointF(.7*width,.935*height),QtCore.QPointF(.7*width,.965*height)) painter.drawLine(QtCore.QPointF(.95*width,.935*height),QtCore.QPointF(.95*width,.965*height)) if scalebartext: dist = u"%.1f \u212B" % (ratio*self.viewsize/2.*self.RADIUS/60.) dist_q = QtCore.QString(dist) fm = QtGui.QFontMetrics(font) x_shift = fm.width(dist_q)*.5 painter.drawText(QtCore.QPointF(0.825*width-x_shift,0.925*height),dist_q) if hasattr(self,"axes_mag") and self.axes_mag and self.show_axes: axes_pos = QtCore.QPointF(theImage.width()*(self.axes_position[0]/2.+0.5),theImage.height()*(1.0-(self.axes_position[1]/2.+0.5))) if bright_y <0.5: pen = QtGui.QPen(QtGui.QColor(255,255,255)) else: pen = QtGui.QPen(QtGui.QColor(0,0,0)) xaxis = self.quat.getMatrix()*pygl_coord.Cartesian(1,0,0); yaxis = self.quat.getMatrix()*pygl_coord.Cartesian(0,1,0) zaxis = self.quat.getMatrix()*pygl_coord.Cartesian(0,0,1) zreal = pygl_coord.Cartesian(0,0,1) xproj = xaxis; xproj.set_z(0); yproj = yaxis; yproj.set_z(0); zproj = zaxis; zproj.set_z(0); xprime = pygl_coord.Cartesian.CrossProduct(xproj,zreal); xprime.normalize() yprime = pygl_coord.Cartesian.CrossProduct(yproj,zreal); yprime.normalize() zprime = pygl_coord.Cartesian.CrossProduct(zproj,zreal); zprime.normalize() xprime = xprime*0.004*theImage.width() yprime = yprime*0.004*theImage.width() zprime = zprime*0.004*theImage.width() xaxis = xaxis*0.04*theImage.width() yaxis = yaxis*0.04*theImage.width() zaxis = zaxis*0.04*theImage.width() xppos = QtCore.QPointF(xprime.get_x(),-xprime.get_y()) yppos = QtCore.QPointF(yprime.get_x(),-yprime.get_y()) zppos = QtCore.QPointF(zprime.get_x(),-zprime.get_y()) xpos = QtCore.QPointF(xaxis.get_x(),-xaxis.get_y())+axes_pos ypos = QtCore.QPointF(yaxis.get_x(),-yaxis.get_y())+axes_pos zpos = QtCore.QPointF(zaxis.get_x(),-zaxis.get_y())+axes_pos xposarrow = QtCore.QPointF(0.8*xaxis.get_x(),-0.8*xaxis.get_y())+axes_pos yposarrow = QtCore.QPointF(0.8*yaxis.get_x(),-0.8*yaxis.get_y())+axes_pos zposarrow = QtCore.QPointF(0.8*zaxis.get_x(),-0.8*zaxis.get_y())+axes_pos xpostext = QtCore.QPointF(1.2*xaxis.get_x(),-1.2*xaxis.get_y())+axes_pos ypostext = QtCore.QPointF(1.2*yaxis.get_x(),-1.2*yaxis.get_y())+axes_pos zpostext = QtCore.QPointF(1.2*zaxis.get_x(),-1.2*zaxis.get_y())+axes_pos pen.setWidth(2*self.axes_mag) font = QtGui.QFont("Times",24*self.axes_mag) painter.setPen(pen) painter.setFont(font) painter.drawLine(axes_pos,xpos) painter.drawLine(axes_pos,ypos) painter.drawLine(axes_pos,zpos) xpp = xposarrow + xppos xpm = xposarrow - xppos painter.drawLine(xpos,xpp) painter.drawLine(xpos,xpm) ypp = yposarrow + yppos ypm = yposarrow - yppos painter.drawLine(ypos,ypp) painter.drawLine(ypos,ypm) zpp = zposarrow + zppos zpm = zposarrow - zppos painter.drawLine(zpos,zpp) painter.drawLine(zpos,zpm) painter.drawText(xpostext,'x') painter.drawText(ypostext,'y') painter.drawText(zpostext,'z') painter.end() def screenshot(self): #print "MGGLWidget.screenshot"; sys.stdout.flush() if sys.platform != "win32" and self.drawTextSeparately: self.drawText = False import global_definitions misco = global_definitions.PM('miscell_prefs') fog_text = misco.get('fog_text') doText=True """ if fog_text: print "Not doing separate text, because of fogginess. But should be scaled",self.fontScaling self.drawText = True doText=False """ self.updateGL() self.updateGL() iinfo = opengl.get_pixdata() iinfo.invert() if doText and sys.platform != "win32" and self.drawTextSeparately: import tempfile f = tempfile.mkstemp(".png") iinfo.writepng(f[0]) width = iinfo.get_width() height = iinfo.get_height() i = 0 bright_y = self.bgcolour.redF()*0.299 + self.bgcolour.greenF()*0.587 + self.bgcolour.blueF()*0.114; quat = pygl_coord.Quat(self.quat) quat.postMult(self.extra_quat) viewport = pygl_coord.inta(4) opengl.glGetIntegerv(opengl.GL_VIEWPORT,viewport); tl = opengl.getxyzc(viewport[0],viewport[1])[0]; bl = opengl.getxyzc(viewport[0],viewport[3])[0]; yscale = (tl-bl).length() scale = yscale import FontedPositionedStrings pixmap = QtGui.QPixmap(f[1]) painter = QtGui.QPainter() painter.begin(pixmap) import global_definitions misco = global_definitions.PM('miscell_prefs') tlb = misco.get('text_label_background') bgcol = None if tlb: text_label_background_colour = misco.get('text_label_background_colour') if text_label_background_colour: if text_label_background_colour == "default": bgcol = (self.bgcolour.redF(),self.bgcolour.greenF(),self.bgcolour.blueF()) else: bgcol = cprim.RGBReps.GetColour(text_label_background_colour.replace('_',' ')) for go in self.go: if go.obj.visible>0: prims = go.obj.GetTextPrimitives() for prim in prims: text,isBill,cart = prim.GetText(),prim.IsBillBoard(),prim.GetVertices()[0] cartOrig = cart font = QtGui.QFont(prim.GetFontFamily(),prim.GetFontSize()) if prim.GetFontSlant() == "o" or prim.GetFontSlant() == "i": font.setItalic(True) else: font.setItalic(False) if prim.GetFontWeight() == "bold": font.setWeight(QtGui.QFont.Bold) if prim.GetFontUnderline(): font.setUnderline(True) else: font.setUnderline(False) s = FontedPositionedStrings.FontedPositionedStringsFromText(text,fontScaling=self.fontScaling,defaultFont=font) descent = 0 if isBill: xfrac,yfrac = cart.get_x(),cart.get_y() x,y = xfrac*width, height-int(yfrac*height)-1 # Cannot help think we need the same for non-billboards. descent = s.getDescent() else: cart = quat.getMatrix()*(cart+pygl_coord.Cartesian(self.rpos)) x,y = cart.get_x(),cart.get_y() xfrac,yfrac = x/scale+0.5, y/scale+0.5 x,y = int((xfrac*height)+(width-height)/2.0),height-int((yfrac*height))-1 #pixmaps = renderStringToPixmap(text) #print self.fontScaling brect = s.getBoundingRect() if bgcol: painter.setPen(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2])) painter.setBrush(QtGui.QBrush(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2]))) painter.drawRect(x,y+descent,brect.width(),-brect.height()) if bright_y <0.5: painter.setPen(QtGui.QColor(255,255,255)) else: painter.setPen(QtGui.QColor(0,0,0)) FontedPositionedStrings.drawFontedPositionedStrings(s.getStrings(),painter,x,y-descent,defaultFont=font) symm_mat = [] if not isBill: if hasattr(go,"symmetry_dependent") and go.symmetry_dependent and go.symmetry_dependent.draw_symmetry and hasattr(go.symmetry_dependent.obj,"GetNumSymmetryMatrices"): if go.symmetry_dependent.symmetry_labels: nsym = go.symmetry_dependent.obj.GetNumSymmetryMatrices() symm_mat = pygl_coord.MatrixVector(go.symmetry_dependent.obj.symm_mat) if hasattr(go,"draw_symmetry") and go.draw_symmetry and hasattr(go.obj,"GetNumSymmetryMatrices"): nsym = go.obj.GetNumSymmetryMatrices() symm_mat = pygl_coord.MatrixVector(go.obj.symm_mat) for mat in symm_mat: cartSym = quat.getMatrix()*(mat*cartOrig+pygl_coord.Cartesian(self.rpos)) xSym,ySym = cartSym.get_x(),cartSym.get_y() xfracSym,yfracSym = xSym/scale+0.5, ySym/scale+0.5 xSym,ySym = int((xfracSym*height)+(width-height)/2.0),height-int((yfracSym*height))-1 if bgcol: painter.setPen(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2])) painter.setBrush(QtGui.QBrush(QtGui.QColor.fromRgbF(bgcol[0],bgcol[1],bgcol[2]))) painter.drawRect(xSym,ySym+descent,brect.width(),-brect.height()) if bright_y <0.5: painter.setPen(QtGui.QColor(255,255,255)) else: painter.setPen(QtGui.QColor(0,0,0)) FontedPositionedStrings.drawFontedPositionedStrings(s.getStrings(),painter,xSym,ySym-descent,defaultFont=font) painter.end() f = tempfile.mkstemp(".png") pixmap.toImage().save(f[1]) iinfo = image_info.image_info(f[1]) self.drawText = True os.close(f[0]) self.updateGL() return iinfo def SetupKeyboard(self): self.keys_down[QtCore.Qt.Key_Escape]=0 self.keys_down[QtCore.Qt.Key_Tab]=0 self.keys_down[QtCore.Qt.Key_Backtab]=0 self.keys_down[QtCore.Qt.Key_Backspace]=0 self.keys_down[QtCore.Qt.Key_Return]=0 self.keys_down[QtCore.Qt.Key_Enter]=0 self.keys_down[QtCore.Qt.Key_Insert]=0 self.keys_down[QtCore.Qt.Key_Delete]=0 self.keys_down[QtCore.Qt.Key_Pause]=0 self.keys_down[QtCore.Qt.Key_Print]=0 self.keys_down[QtCore.Qt.Key_SysReq]=0 self.keys_down[QtCore.Qt.Key_Clear]=0 self.keys_down[QtCore.Qt.Key_Home]=0 self.keys_down[QtCore.Qt.Key_End]=0 self.keys_down[QtCore.Qt.Key_Left]=0 self.keys_down[QtCore.Qt.Key_Up]=0 self.keys_down[QtCore.Qt.Key_Right]=0 self.keys_down[QtCore.Qt.Key_Down]=0 self.keys_down[QtCore.Qt.Key_PageUp]=0 self.keys_down[QtCore.Qt.Key_PageDown]=0 self.keys_down[QtCore.Qt.Key_Shift]=0 self.keys_down[QtCore.Qt.Key_Control]=0 self.keys_down[QtCore.Qt.Key_Meta]=0 self.keys_down[QtCore.Qt.Key_Alt]=0 self.keys_down[QtCore.Qt.Key_AltGr]=0 self.keys_down[QtCore.Qt.Key_CapsLock]=0 self.keys_down[QtCore.Qt.Key_NumLock]=0 self.keys_down[QtCore.Qt.Key_ScrollLock]=0 self.keys_down[QtCore.Qt.Key_F1]=0 self.keys_down[QtCore.Qt.Key_F2]=0 self.keys_down[QtCore.Qt.Key_F3]=0 self.keys_down[QtCore.Qt.Key_F4]=0 self.keys_down[QtCore.Qt.Key_F5]=0 self.keys_down[QtCore.Qt.Key_F6]=0 self.keys_down[QtCore.Qt.Key_F7]=0 self.keys_down[QtCore.Qt.Key_F8]=0 self.keys_down[QtCore.Qt.Key_F9]=0 self.keys_down[QtCore.Qt.Key_F10]=0 self.keys_down[QtCore.Qt.Key_F11]=0 self.keys_down[QtCore.Qt.Key_F12]=0 self.keys_down[QtCore.Qt.Key_F13]=0 self.keys_down[QtCore.Qt.Key_F14]=0 self.keys_down[QtCore.Qt.Key_F15]=0 self.keys_down[QtCore.Qt.Key_F16]=0 self.keys_down[QtCore.Qt.Key_F17]=0 self.keys_down[QtCore.Qt.Key_F18]=0 self.keys_down[QtCore.Qt.Key_F19]=0 self.keys_down[QtCore.Qt.Key_F20]=0 self.keys_down[QtCore.Qt.Key_F21]=0 self.keys_down[QtCore.Qt.Key_F22]=0 self.keys_down[QtCore.Qt.Key_F23]=0 self.keys_down[QtCore.Qt.Key_F24]=0 self.keys_down[QtCore.Qt.Key_F25]=0 self.keys_down[QtCore.Qt.Key_F26]=0 self.keys_down[QtCore.Qt.Key_F27]=0 self.keys_down[QtCore.Qt.Key_F28]=0 self.keys_down[QtCore.Qt.Key_F29]=0 self.keys_down[QtCore.Qt.Key_F30]=0 self.keys_down[QtCore.Qt.Key_F31]=0 self.keys_down[QtCore.Qt.Key_F32]=0 self.keys_down[QtCore.Qt.Key_F33]=0 self.keys_down[QtCore.Qt.Key_F34]=0 self.keys_down[QtCore.Qt.Key_F35]=0 self.keys_down[QtCore.Qt.Key_Super_L]=0 self.keys_down[QtCore.Qt.Key_Super_R]=0 self.keys_down[QtCore.Qt.Key_Menu]=0 self.keys_down[QtCore.Qt.Key_Hyper_L]=0 self.keys_down[QtCore.Qt.Key_Hyper_R]=0 self.keys_down[QtCore.Qt.Key_Help]=0 self.keys_down[QtCore.Qt.Key_Direction_L]=0 self.keys_down[QtCore.Qt.Key_Direction_R]=0 self.keys_down[QtCore.Qt.Key_Space]=0 self.keys_down[QtCore.Qt.Key_Any]=0 self.keys_down[QtCore.Qt.Key_Exclam]=0 self.keys_down[QtCore.Qt.Key_QuoteDbl]=0 self.keys_down[QtCore.Qt.Key_NumberSign]=0 self.keys_down[QtCore.Qt.Key_Dollar]=0 self.keys_down[QtCore.Qt.Key_Percent]=0 self.keys_down[QtCore.Qt.Key_Ampersand]=0 self.keys_down[QtCore.Qt.Key_Apostrophe]=0 self.keys_down[QtCore.Qt.Key_ParenLeft]=0 self.keys_down[QtCore.Qt.Key_ParenRight]=0 self.keys_down[QtCore.Qt.Key_Asterisk]=0 self.keys_down[QtCore.Qt.Key_Plus]=0 self.keys_down[QtCore.Qt.Key_Comma]=0 self.keys_down[QtCore.Qt.Key_Minus]=0 self.keys_down[QtCore.Qt.Key_Period]=0 self.keys_down[QtCore.Qt.Key_Slash]=0 self.keys_down[QtCore.Qt.Key_0]=0 self.keys_down[QtCore.Qt.Key_1]=0 self.keys_down[QtCore.Qt.Key_2]=0 self.keys_down[QtCore.Qt.Key_3]=0 self.keys_down[QtCore.Qt.Key_4]=0 self.keys_down[QtCore.Qt.Key_5]=0 self.keys_down[QtCore.Qt.Key_6]=0 self.keys_down[QtCore.Qt.Key_7]=0 self.keys_down[QtCore.Qt.Key_8]=0 self.keys_down[QtCore.Qt.Key_9]=0 self.keys_down[QtCore.Qt.Key_Colon]=0 self.keys_down[QtCore.Qt.Key_Semicolon]=0 self.keys_down[QtCore.Qt.Key_Less]=0 self.keys_down[QtCore.Qt.Key_Equal]=0 self.keys_down[QtCore.Qt.Key_Greater]=0 self.keys_down[QtCore.Qt.Key_Question]=0 self.keys_down[QtCore.Qt.Key_At]=0 self.keys_down[QtCore.Qt.Key_A]=0 self.keys_down[QtCore.Qt.Key_B]=0 self.keys_down[QtCore.Qt.Key_C]=0 self.keys_down[QtCore.Qt.Key_D]=0 self.keys_down[QtCore.Qt.Key_E]=0 self.keys_down[QtCore.Qt.Key_F]=0 self.keys_down[QtCore.Qt.Key_G]=0 self.keys_down[QtCore.Qt.Key_H]=0 self.keys_down[QtCore.Qt.Key_I]=0 self.keys_down[QtCore.Qt.Key_J]=0 self.keys_down[QtCore.Qt.Key_K]=0 self.keys_down[QtCore.Qt.Key_L]=0 self.keys_down[QtCore.Qt.Key_M]=0 self.keys_down[QtCore.Qt.Key_N]=0 self.keys_down[QtCore.Qt.Key_O]=0 self.keys_down[QtCore.Qt.Key_P]=0 self.keys_down[QtCore.Qt.Key_Q]=0 self.keys_down[QtCore.Qt.Key_R]=0 self.keys_down[QtCore.Qt.Key_S]=0 self.keys_down[QtCore.Qt.Key_T]=0 self.keys_down[QtCore.Qt.Key_U]=0 self.keys_down[QtCore.Qt.Key_V]=0 self.keys_down[QtCore.Qt.Key_W]=0 self.keys_down[QtCore.Qt.Key_X]=0 self.keys_down[QtCore.Qt.Key_Y]=0 self.keys_down[QtCore.Qt.Key_Z]=0 self.keys_down[QtCore.Qt.Key_BracketLeft]=0 self.keys_down[QtCore.Qt.Key_Backslash]=0 self.keys_down[QtCore.Qt.Key_BracketRight]=0 self.keys_down[QtCore.Qt.Key_AsciiCircum]=0 self.keys_down[QtCore.Qt.Key_Underscore]=0 self.keys_down[QtCore.Qt.Key_QuoteLeft]=0 self.keys_down[QtCore.Qt.Key_BraceLeft]=0 self.keys_down[QtCore.Qt.Key_Bar]=0 self.keys_down[QtCore.Qt.Key_BraceRight]=0 self.keys_down[QtCore.Qt.Key_AsciiTilde]=0 self.keys_down[QtCore.Qt.Key_nobreakspace]=0 self.keys_down[QtCore.Qt.Key_exclamdown]=0 self.keys_down[QtCore.Qt.Key_cent]=0 self.keys_down[QtCore.Qt.Key_sterling]=0 self.keys_down[QtCore.Qt.Key_currency]=0 self.keys_down[QtCore.Qt.Key_yen]=0 self.keys_down[QtCore.Qt.Key_brokenbar]=0 self.keys_down[QtCore.Qt.Key_section]=0 self.keys_down[QtCore.Qt.Key_diaeresis]=0 self.keys_down[QtCore.Qt.Key_copyright]=0 self.keys_down[QtCore.Qt.Key_ordfeminine]=0 self.keys_down[QtCore.Qt.Key_guillemotleft]=0 self.keys_down[QtCore.Qt.Key_notsign]=0 self.keys_down[QtCore.Qt.Key_hyphen]=0 self.keys_down[QtCore.Qt.Key_registered]=0 self.keys_down[QtCore.Qt.Key_macron]=0 self.keys_down[QtCore.Qt.Key_degree]=0 self.keys_down[QtCore.Qt.Key_plusminus]=0 self.keys_down[QtCore.Qt.Key_twosuperior]=0 self.keys_down[QtCore.Qt.Key_threesuperior]=0 self.keys_down[QtCore.Qt.Key_acute]=0 self.keys_down[QtCore.Qt.Key_mu]=0 self.keys_down[QtCore.Qt.Key_paragraph]=0 self.keys_down[QtCore.Qt.Key_periodcentered]=0 self.keys_down[QtCore.Qt.Key_cedilla]=0 self.keys_down[QtCore.Qt.Key_onesuperior]=0 self.keys_down[QtCore.Qt.Key_masculine]=0 self.keys_down[QtCore.Qt.Key_guillemotright]=0 self.keys_down[QtCore.Qt.Key_onequarter]=0 self.keys_down[QtCore.Qt.Key_onehalf]=0 self.keys_down[QtCore.Qt.Key_threequarters]=0 self.keys_down[QtCore.Qt.Key_questiondown]=0 self.keys_down[QtCore.Qt.Key_Agrave]=0 self.keys_down[QtCore.Qt.Key_Aacute]=0 self.keys_down[QtCore.Qt.Key_Acircumflex]=0 self.keys_down[QtCore.Qt.Key_Atilde]=0 self.keys_down[QtCore.Qt.Key_Adiaeresis]=0 self.keys_down[QtCore.Qt.Key_Aring]=0 self.keys_down[QtCore.Qt.Key_AE]=0 self.keys_down[QtCore.Qt.Key_Ccedilla]=0 self.keys_down[QtCore.Qt.Key_Egrave]=0 self.keys_down[QtCore.Qt.Key_Eacute]=0 self.keys_down[QtCore.Qt.Key_Ecircumflex]=0 self.keys_down[QtCore.Qt.Key_Ediaeresis]=0 self.keys_down[QtCore.Qt.Key_Igrave]=0 self.keys_down[QtCore.Qt.Key_Iacute]=0 self.keys_down[QtCore.Qt.Key_Icircumflex]=0 self.keys_down[QtCore.Qt.Key_Idiaeresis]=0 self.keys_down[QtCore.Qt.Key_ETH]=0 self.keys_down[QtCore.Qt.Key_Ntilde]=0 self.keys_down[QtCore.Qt.Key_Ograve]=0 self.keys_down[QtCore.Qt.Key_Oacute]=0 self.keys_down[QtCore.Qt.Key_Ocircumflex]=0 self.keys_down[QtCore.Qt.Key_Otilde]=0 self.keys_down[QtCore.Qt.Key_Odiaeresis]=0 self.keys_down[QtCore.Qt.Key_multiply]=0 self.keys_down[QtCore.Qt.Key_Ooblique]=0 self.keys_down[QtCore.Qt.Key_Ugrave]=0 self.keys_down[QtCore.Qt.Key_Uacute]=0 self.keys_down[QtCore.Qt.Key_Ucircumflex]=0 self.keys_down[QtCore.Qt.Key_Udiaeresis]=0 self.keys_down[QtCore.Qt.Key_Yacute]=0 self.keys_down[QtCore.Qt.Key_THORN]=0 self.keys_down[QtCore.Qt.Key_ssharp]=0 self.keys_down[QtCore.Qt.Key_division]=0 self.keys_down[QtCore.Qt.Key_ydiaeresis]=0 self.keys_down[QtCore.Qt.Key_Multi_key]=0 self.keys_down[QtCore.Qt.Key_Codeinput]=0 self.keys_down[QtCore.Qt.Key_SingleCandidate]=0 self.keys_down[QtCore.Qt.Key_MultipleCandidate]=0 self.keys_down[QtCore.Qt.Key_PreviousCandidate]=0 self.keys_down[QtCore.Qt.Key_Mode_switch]=0 self.keys_down[QtCore.Qt.Key_Kanji]=0 self.keys_down[QtCore.Qt.Key_Muhenkan]=0 self.keys_down[QtCore.Qt.Key_Henkan]=0 self.keys_down[QtCore.Qt.Key_Romaji]=0 self.keys_down[QtCore.Qt.Key_Hiragana]=0 self.keys_down[QtCore.Qt.Key_Katakana]=0 self.keys_down[QtCore.Qt.Key_Hiragana_Katakana]=0 self.keys_down[QtCore.Qt.Key_Zenkaku]=0 self.keys_down[QtCore.Qt.Key_Hankaku]=0 self.keys_down[QtCore.Qt.Key_Zenkaku_Hankaku]=0 self.keys_down[QtCore.Qt.Key_Touroku]=0 self.keys_down[QtCore.Qt.Key_Massyo]=0 self.keys_down[QtCore.Qt.Key_Kana_Lock]=0 self.keys_down[QtCore.Qt.Key_Kana_Shift]=0 self.keys_down[QtCore.Qt.Key_Eisu_Shift]=0 self.keys_down[QtCore.Qt.Key_Eisu_toggle]=0 self.keys_down[QtCore.Qt.Key_Hangul]=0 self.keys_down[QtCore.Qt.Key_Hangul_Start]=0 self.keys_down[QtCore.Qt.Key_Hangul_End]=0 self.keys_down[QtCore.Qt.Key_Hangul_Hanja]=0 self.keys_down[QtCore.Qt.Key_Hangul_Jamo]=0 self.keys_down[QtCore.Qt.Key_Hangul_Romaja]=0 self.keys_down[QtCore.Qt.Key_Hangul_Jeonja]=0 self.keys_down[QtCore.Qt.Key_Hangul_Banja]=0 self.keys_down[QtCore.Qt.Key_Hangul_PreHanja]=0 self.keys_down[QtCore.Qt.Key_Hangul_PostHanja]=0 self.keys_down[QtCore.Qt.Key_Hangul_Special]=0 self.keys_down[QtCore.Qt.Key_Dead_Grave]=0 self.keys_down[QtCore.Qt.Key_Dead_Acute]=0 self.keys_down[QtCore.Qt.Key_Dead_Circumflex]=0 self.keys_down[QtCore.Qt.Key_Dead_Tilde]=0 self.keys_down[QtCore.Qt.Key_Dead_Macron]=0 self.keys_down[QtCore.Qt.Key_Dead_Breve]=0 self.keys_down[QtCore.Qt.Key_Dead_Abovedot]=0 self.keys_down[QtCore.Qt.Key_Dead_Diaeresis]=0 self.keys_down[QtCore.Qt.Key_Dead_Abovering]=0 self.keys_down[QtCore.Qt.Key_Dead_Doubleacute]=0 self.keys_down[QtCore.Qt.Key_Dead_Caron]=0 self.keys_down[QtCore.Qt.Key_Dead_Cedilla]=0 self.keys_down[QtCore.Qt.Key_Dead_Ogonek]=0 self.keys_down[QtCore.Qt.Key_Dead_Iota]=0 self.keys_down[QtCore.Qt.Key_Dead_Voiced_Sound]=0 self.keys_down[QtCore.Qt.Key_Dead_Semivoiced_Sound]=0 self.keys_down[QtCore.Qt.Key_Dead_Belowdot]=0 self.keys_down[QtCore.Qt.Key_Dead_Hook]=0 self.keys_down[QtCore.Qt.Key_Dead_Horn]=0 self.keys_down[QtCore.Qt.Key_Back]=0 self.keys_down[QtCore.Qt.Key_Forward]=0 self.keys_down[QtCore.Qt.Key_Stop]=0 self.keys_down[QtCore.Qt.Key_Refresh]=0 self.keys_down[QtCore.Qt.Key_VolumeDown]=0 self.keys_down[QtCore.Qt.Key_VolumeMute]=0 self.keys_down[QtCore.Qt.Key_VolumeUp]=0 self.keys_down[QtCore.Qt.Key_BassBoost]=0 self.keys_down[QtCore.Qt.Key_BassUp]=0 self.keys_down[QtCore.Qt.Key_BassDown]=0 self.keys_down[QtCore.Qt.Key_TrebleUp]=0 self.keys_down[QtCore.Qt.Key_TrebleDown]=0 self.keys_down[QtCore.Qt.Key_MediaPlay]=0 self.keys_down[QtCore.Qt.Key_MediaStop]=0 self.keys_down[QtCore.Qt.Key_MediaPrevious]=0 self.keys_down[QtCore.Qt.Key_MediaNext]=0 self.keys_down[QtCore.Qt.Key_MediaRecord]=0 self.keys_down[QtCore.Qt.Key_HomePage]=0 self.keys_down[QtCore.Qt.Key_Favorites]=0 self.keys_down[QtCore.Qt.Key_Search]=0 self.keys_down[QtCore.Qt.Key_Standby]=0 self.keys_down[QtCore.Qt.Key_OpenUrl]=0 self.keys_down[QtCore.Qt.Key_LaunchMail]=0 self.keys_down[QtCore.Qt.Key_LaunchMedia]=0 self.keys_down[QtCore.Qt.Key_Launch0]=0 self.keys_down[QtCore.Qt.Key_Launch1]=0 self.keys_down[QtCore.Qt.Key_Launch2]=0 self.keys_down[QtCore.Qt.Key_Launch3]=0 self.keys_down[QtCore.Qt.Key_Launch4]=0 self.keys_down[QtCore.Qt.Key_Launch5]=0 self.keys_down[QtCore.Qt.Key_Launch6]=0 self.keys_down[QtCore.Qt.Key_Launch7]=0 self.keys_down[QtCore.Qt.Key_Launch8]=0 self.keys_down[QtCore.Qt.Key_Launch9]=0 self.keys_down[QtCore.Qt.Key_LaunchA]=0 self.keys_down[QtCore.Qt.Key_LaunchB]=0 self.keys_down[QtCore.Qt.Key_LaunchC]=0 self.keys_down[QtCore.Qt.Key_LaunchD]=0 self.keys_down[QtCore.Qt.Key_LaunchE]=0 self.keys_down[QtCore.Qt.Key_LaunchF]=0 self.keys_down[QtCore.Qt.Key_MediaLast]=0 self.keys_down[QtCore.Qt.Key_unknown]=0 self.keys_down[QtCore.Qt.Key_Call]=0 self.keys_down[QtCore.Qt.Key_Context1]=0 self.keys_down[QtCore.Qt.Key_Context2]=0 self.keys_down[QtCore.Qt.Key_Context3]=0 self.keys_down[QtCore.Qt.Key_Context4]=0 self.keys_down[QtCore.Qt.Key_Flip]=0 self.keys_down[QtCore.Qt.Key_Hangup]=0 self.keys_down[QtCore.Qt.Key_No]=0 self.keys_down[QtCore.Qt.Key_Select]=0 self.keys_down[QtCore.Qt.Key_Yes]=0 self.keys_down[QtCore.Qt.Key_Execute]=0 self.keys_down[QtCore.Qt.Key_Printer]=0 self.keys_down[QtCore.Qt.Key_Play]=0 self.keys_down[QtCore.Qt.Key_Sleep]=0 self.keys_down[QtCore.Qt.Key_Zoom]=0 self.keys_down[QtCore.Qt.Key_Cancel]=0 def SetGOParams(self, params=None): pass def reInitializeTextPrims(self): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() for go in self.go: go.obj.reInitializeTextPrims() def rebuildDisplayObject(self, go=None,redraw=0): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.rebuildDisplayObject(self, go,redraw) def removeDisplayObject(self, go_in=None,redraw=0): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.removeDisplayObject(self, go_in,redraw) def addDisplayObject(self, go=None,redraw=0): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.addDisplayObject(self, go,redraw) def __init__(self,parent=None,share=None,format=None,use_pbuffer=False,pbuffer_size=QtCore.QSize(600,600)): if format: QtOpenGL.QGLWidget.__init__(self,format,parent,share) #print "Samples",format.samples(),format.sampleBuffers() else: QtOpenGL.QGLWidget.__init__(self,parent,share) #print "No format specified" #print "my Samples",self.format().samples(),self.format().sampleBuffers() """ # Testing import mmdb, SimpleObject mmdb.InitMatType() molHnd = mmdb.CMMDBManager() molHnd.SetFlag(mmdb.MMDBF_AllowDuplChainID) molHnd.ReadCoorFile("/richelieu/stuart/ccp4-jhbuild-distutils/1sva_1.mmol") self.sillyobj = SimpleObject.SimpleObject(molHnd) """ MGGLWidgetGL.__init__(self,parent,share,format) self.setAcceptDrops(1) self.use_pbuffer=use_pbuffer if self.use_pbuffer: self.pbuffer = QtOpenGL.QGLPixelBuffer(pbuffer_size,self.format(),self) self.BindOffScreenBuffer() # A silly number, out of normal range, to force matrix creation first time round. self.stereo_shear_separation = 1000 self.setFocusPolicy(QtCore.Qt.StrongFocus) self.SetupKeyboard() self.qkey_timer = QtCore.QTimer(self) self.connect(self.qkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.akey_timer = QtCore.QTimer(self) self.connect(self.akey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.okey_timer = QtCore.QTimer(self) self.connect(self.okey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.pkey_timer = QtCore.QTimer(self) self.connect(self.pkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.nkey_timer = QtCore.QTimer(self) self.connect(self.nkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.mkey_timer = QtCore.QTimer(self) self.connect(self.mkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.leftkey_timer = QtCore.QTimer(self) self.connect(self.leftkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.rightkey_timer = QtCore.QTimer(self) self.connect(self.rightkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.upkey_timer = QtCore.QTimer(self) self.connect(self.upkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) self.downkey_timer = QtCore.QTimer(self) self.connect(self.downkey_timer,QtCore.SIGNAL('timeout()'),self.lrudqaopnmkey_handler) #self.roll_timer = QtCore.QTimer(self) #self.connect(self.roll_timer,QtCore.SIGNAL('timeout()'),self.roll_handler) #self.record_timer = QtCore.QTimer(self) #self.connect(self.record_timer,QtCore.SIGNAL('timeout()'),self.record_handler) self.pluskey_timer = QtCore.QTimer(self) self.connect(self.pluskey_timer,QtCore.SIGNAL('timeout()'),self.pluskey_handler) self.minuskey_timer = QtCore.QTimer(self) self.connect(self.minuskey_timer,QtCore.SIGNAL('timeout()'),self.minuskey_handler) self.context_menu = QtGui.QMenu(self.tr('Context')) keyPressEater = KeyPressEater(self) self.context_menu.installEventFilter(keyPressEater) self.connect(self.context_menu,QtCore.SIGNAL('aboutToShow()'),self.aboutToShowHandler) self.connect(self.context_menu,QtCore.SIGNAL('aboutToHide()'),self.aboutToHideHandler) # This is an annoying hack since aboutToShow seems to always be triggered twice. self.showing_context_menu = False self.contextMenuHandler = self.defaultContextMenuHandler self.doubleClickHandler = self.defaultDoubleClickHandler self.leftClickHandler = self.defaultLeftClickHandler self.contextMenuPickEvent = None import UtilityThread self.mt = UtilityThread.UtilityThread() self.connect(self.mt,QtCore.SIGNAL('finished()'),self.UtilityThreadFinished) self.lastEventType=None self.setDefaultMouseBindings() self.setup_colour_pointers() """ if QtCore.QT_VERSION >= 0x40600 and QtCore.PYQT_VERSION >= 0x040700 and sip.SIP_VERSION >= 0x040a00: #print "Maybe have gestures" self.grabGesture(QtCore.Qt.PanGesture); self.grabGesture(QtCore.Qt.PinchGesture); self.grabGesture(QtCore.Qt.SwipeGesture); #print "Hopefully grabbed gestures" """ self.show_fps = False self.current_fps_text = "0" self.useCootMouseBindings = False def defaultLeftClickHandler(self,pickevent): pass def defaultDoubleClickHandler(self,pickevent): pass def defaultContextMenuHandler(self,pickevent): pass def UtilityThreadFinished(self): id = len(self.go)-1 go = self.go[id] self.buildlist(go,self.listids[id]) self.updateGL() statusBar = GetMainWindow().statusBar() statusBar.showMessage("") def minimumSizeHint(self): return QtCore.QSize(150, 150) def sizeHint(self): return QtCore.QSize(800, 800) def setLights(self,lights): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.setLights(self, lights) def getOpenGLLightParameters(self,lightID): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() return MGGLWidgetGL.getOpenGLLightParameters(self, lightID) def getLights(self): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() return MGGLWidgetGL.getLights(self) def initializeGL(self): if self.use_pbuffer: self.BindOffScreenBuffer() self.qglClearColor(self.bgcolour) MGGLWidgetGL.initializeGL(self) if QtOpenGL.QGLFramebufferObject.hasOpenGLFramebufferObjects (): reqW = 2048 reqH = 2048 self.offScreenBufferDepth = opengl.MGDepthFramebufferObject(1024,1024) #print "Got depth map"; sys.stdout.flush() if not os.environ.has_key("CCP4MG_DEBUG_SHADOWS"): self.offScreenBufferShadow = opengl.MGDepthFramebufferObject(reqW,reqH) #print "Got shadow map"; sys.stdout.flush() #reqW = 2048 #reqH = 2048 fmt = QtOpenGL.QGLFramebufferObjectFormat() fmt.setAttachment(QtOpenGL.QGLFramebufferObject.CombinedDepthStencil) #fmt.setSamples(self.format().samples()) #self.offScreenBufferMirror = QtOpenGL.QGLFramebufferObject(QtCore.QSize(reqW,reqH),fmt) #self.offScreenBufferTextureMirror = QtOpenGL.QGLFramebufferObject(QtCore.QSize(reqW,reqH)) #self.offScreenBufferOther = QtOpenGL.QGLFramebufferObject(QtCore.QSize(reqW,reqH)) self.offScreenBufferSSAO = QtOpenGL.QGLFramebufferObject(QtCore.QSize(1024,1024)) self.offScreenBufferEdge = QtOpenGL.QGLFramebufferObject(QtCore.QSize(1024,1024)) self.offScreenBufferBlur = QtOpenGL.QGLFramebufferObject(QtCore.QSize(1024,1024)) self.offScreenBufferNormal = QtOpenGL.QGLFramebufferObject(QtCore.QSize(1024,1024),fmt) if os.environ.has_key("CCP4MG_DEBUG_SHADOWS"): self.offScreenBufferShadow = QtOpenGL.QGLFramebufferObject(QtCore.QSize(1024,1024),fmt) def setShader(self,vertexShader,fragmentShader): if not vertexShader or not fragmentShader: return if vertexShader == self.vertexShader and fragmentShader == self.fragmentShader: return try: import glShaders self.shader = glShaders.MGGLShader(vertexShader,fragmentShader) self.vertexShader = vertexShader self.fragmentShader = fragmentShader self.shader.setShadowState(False) except: QtGui.QMessageBox.critical(None, "No shader support", "This version of ccp4mg does not have shader support.", QtGui.QMessageBox.Ok ) def setup_clipping(self,slab_offset=None,slab_width=None): if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.setup_clipping(self,slab_offset,slab_width) def setup_fog(self): if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.setup_fog(self) def setupModelview(self,furtherQuat=None,furtherMatrix=None): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.setupModelview(self,furtherQuat,furtherMatrix) def paintGL(self): """ # Testing opengl.glLoadIdentity(); opengl.glTranslatef(0,0,-600); opengl.glScalef(60.0/float(self.RADIUS),60.0/float(self.RADIUS),60.0/float(self.RADIUS)) glrotmat = self.quat.getInvMatrix().to_dp() opengl.glMultMatrixd(glrotmat) opengl.delcdp(glrotmat) self.qglClearColor(QtGui.QColor(QtCore.Qt.white)) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT) opengl.glDisable(opengl.GL_LIGHTING); opengl.glEnableClientState(opengl.GL_VERTEX_ARRAY) opengl.glEnableClientState(opengl.GL_COLOR_ARRAY) if hasattr(self,"sillyobj") and hasattr(self.sillyobj,"draw") and callable(self.sillyobj.draw): self.sillyobj.draw() self.showFPS() return """ if self.shaders_on and hasattr(self,"shader") and self.shader: ssaoOnLoc = self.shader.getUniformLocation("ssaoOn") self.shader.Uniform1f(ssaoOnLoc,False) ssaoOnLocCircle = self.circleShader.getUniformLocation("ssaoOn") self.circleShader.Uniform1f(ssaoOnLocCircle,False) edgeDetectOnLoc = self.shader.getUniformLocation("edgeDetectOn") self.shader.Uniform1f(edgeDetectOnLoc,False) edgeDetectOnCircleLoc = self.circleShader.getUniformLocation("edgeDetectOn") self.circleShader.Uniform1f(edgeDetectOnCircleLoc,False) edgeDetectOnCircleLoc = self.circleShadowShader.getUniformLocation("edgeDetectOn") self.circleShadowShader.Uniform1f(edgeDetectOnCircleLoc,False) if (not self.doMirror and not self.doShadow and not self.doAmbient and not self.doOutline) or not self.shaders_on: if self.shaders_on and hasattr(self,"shader") and self.shader: self.shader.setShadowState(False) self.circleShader.setShadowState(False) ShadowMapLoc = self.shader.getUniformLocation("ShadowMap") self.shader.Uniform1i(ShadowMapLoc,2) ShadowMapLoc = self.circleShader.getUniformLocation("ShadowMap") self.circleShader.Uniform1i(ShadowMapLoc,2) SSAOMapLoc = self.shader.getUniformLocation("SSAOMap") self.shader.Uniform1i(SSAOMapLoc,3) EdgeMapLoc = self.shader.getUniformLocation("EdgeMap") self.shader.Uniform1i(EdgeMapLoc,4) EdgeMapCircleLoc = self.circleShader.getUniformLocation("EdgeMap") self.circleShader.Uniform1i(EdgeMapCircleLoc,4) EdgeMapCircleLoc = self.circleShadowShader.getUniformLocation("EdgeMap") self.circleShadowShader.Uniform1i(EdgeMapCircleLoc,4) if self.multiTextureAvailable: opengl.SetMyTextureUnit(opengl.GL_TEXTURE2); opengl.glBindTexture( opengl.GL_TEXTURE_2D, 0 ); opengl.SetMyTextureUnit(opengl.GL_TEXTURE3); opengl.glBindTexture( opengl.GL_TEXTURE_2D, 0 ); opengl.SetMyTextureUnit(opengl.GL_TEXTURE4); opengl.glBindTexture( opengl.GL_TEXTURE_2D, 0 ); opengl.glDisable(opengl.GL_TEXTURE_2D); opengl.SetMyTextureUnit(opengl.GL_TEXTURE0); opengl.glDisable(opengl.GL_TEXTURE_2D); self.paintGL2() return shaders_on = self.shaders_on use_pbuffer = self.use_pbuffer self.use_pbuffer = False if hasattr(self,"pbuffer"): self.pbuffer.release() self.makeCurrent() if self.doOutline and shaders_on and hasattr(self,"normalAsColourShader") and self.normalAsColourShader: # I am cheating for testing by using SSAO texture location/flag to get this on screen. Will change. self.shaders_on = False self.offScreenBufferNormal.bind() if hasattr(self,"normalAsColourShader"): self.normalAsColourShader.turnOn() reqW = self.offScreenBufferNormal.width() reqH = self.offScreenBufferNormal.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h # FIXME - Do something in render loop about lines, etc. (like with shadows). self.inAmbient = True #print "Call resizeGLMain ambient 1" self.resizeGLMain(reqW,reqH,ratio) self.paintGL2() self.inAmbient = False if hasattr(self,"normalAsColourShader"): self.normalAsColourShader.turnOff() self.offScreenBufferNormal.release() #self.offScreenBufferNormal.toImage().save("normal.png") normalTexture = self.offScreenBufferNormal.texture() # Render depth to texture self.offScreenBufferDepth.bind() reqW = self.offScreenBufferDepth.width() reqH = self.offScreenBufferDepth.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h # FIXME - Do something in render loop about lines, etc. (like with shadows). self.inAmbient = True #print "Call resizeGLMain ambient 1" self.resizeGLMain(reqW,reqH,ratio) #self.shadowShader.turnOn() self.paintGL2() #self.shadowShader.turnOff() self.inAmbient = False #opengl.setTextureMatrix() self.offScreenBufferDepth.release() depthTexture = self.offScreenBufferDepth.texture() # Do Edge detect step, draw onto quad. self.offScreenBufferEdge.bind() reqW = self.offScreenBufferEdge.width() reqH = self.offScreenBufferEdge.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h #print "Call resizeGLMain ambient 2" self.resizeGLMain(reqW,reqH,ratio) depthMapLoc = self.edgeDetectShader.getUniformLocation("depthMap") normalMapLoc = self.edgeDetectShader.getUniformLocation("normalMap") screenWidthLoc = self.edgeDetectShader.getUniformLocation("screenWidth") screenHeightLoc = self.edgeDetectShader.getUniformLocation("screenHeight") self.edgeDetectShader.Uniform1f(screenWidthLoc,reqW) self.edgeDetectShader.Uniform1f(screenHeightLoc,reqH) self.edgeDetectShader.Uniform1i(depthMapLoc,2) self.edgeDetectShader.Uniform1i(normalMapLoc,3) self.edgeDetectShader.turnOn() opengl.SetMyTextureUnit(opengl.GL_TEXTURE2); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,depthTexture) opengl.SetMyTextureUnit(opengl.GL_TEXTURE3); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,normalTexture) opengl.SetMyTextureUnit(opengl.GL_TEXTURE0); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glDisable(opengl.GL_TEXTURE_2D) #self.resizeGLMain(w,h,ratio) opengl.glMatrixMode(opengl.GL_MODELVIEW); opengl.glTranslated(-self.rpos[0],-self.rpos[1],-self.rpos[2]) quat = pygl_coord.Quat(self.quat) glrotmat = quat.getMatrix().to_dp() opengl.glMultMatrixd(glrotmat) opengl.delcdp(glrotmat) # FIXME, do not know why, but this helps us zoom in closer and still have AO work. opengl.glTranslatef(0,0,240) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.edgeDetectShader.turnOff() self.offScreenBufferEdge.release() #self.offScreenBufferEdge.toImage().save("edgenormal.png") # FIXME Copy of SSAO code - need a general method to do this. texture = self.offScreenBufferEdge.texture() # Blur with FBO Ping-pong. # ping ... self.offScreenBufferBlur.bind() self.blurXShader.turnOn() opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.blurXShader.turnOff() self.offScreenBufferBlur.release() # ... pong. texture = self.offScreenBufferBlur.texture() self.offScreenBufferEdge.bind() self.blurYShader.turnOn() #self.resizeGLMain(reqW,reqH,1./ratio) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.blurYShader.turnOff() self.offScreenBufferEdge.release() self.resizeGLMain(w,h,ratio) self.shaders_on = shaders_on # FIXME Need a outline location / texture unit. if shaders_on and hasattr(self,"shader") and self.shader: self.shader.turnOn() self.shader.Uniform1f(edgeDetectOnLoc,True) w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h EdgeMapLoc = self.shader.getUniformLocation("EdgeMap") screenWidthLoc = self.shader.getUniformLocation("screenWidth") screenHeightLoc = self.shader.getUniformLocation("screenHeight") self.shader.Uniform1i(EdgeMapLoc,4) self.shader.Uniform1f(screenWidthLoc,float(self.width())) self.shader.Uniform1f(screenHeightLoc,float(self.height())) opengl.SetMyTextureUnit(opengl.GL_TEXTURE4); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,self.offScreenBufferEdge.texture()) if shaders_on and hasattr(self,"circleShader") and self.circleShader: self.circleShader.turnOn() edgeDetectOnCircleLoc = self.circleShader.getUniformLocation("edgeDetectOn") self.circleShader.Uniform1f(edgeDetectOnCircleLoc,True) EdgeMapShadowLoc = self.circleShader.getUniformLocation("EdgeMap") screenWidthShadowLoc = self.circleShader.getUniformLocation("screenWidth") screenHeightShadowLoc = self.circleShader.getUniformLocation("screenHeight") self.circleShader.Uniform1i(EdgeMapShadowLoc,4) self.circleShader.Uniform1f(screenWidthShadowLoc,float(self.width())) self.circleShader.Uniform1f(screenHeightShadowLoc,float(self.height())) opengl.SetMyTextureUnit(opengl.GL_TEXTURE4); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,self.offScreenBufferEdge.texture()) if shaders_on and hasattr(self,"circleShadowShader") and self.circleShadowShader: self.circleShadowShader.turnOn() edgeDetectOnCircleLoc = self.circleShadowShader.getUniformLocation("edgeDetectOn") self.circleShadowShader.Uniform1f(edgeDetectOnCircleLoc,True) EdgeMapShadowLoc = self.circleShadowShader.getUniformLocation("EdgeMap") screenWidthShadowLoc = self.circleShadowShader.getUniformLocation("screenWidth") screenHeightShadowLoc = self.circleShadowShader.getUniformLocation("screenHeight") self.circleShadowShader.Uniform1i(EdgeMapShadowLoc,4) self.circleShadowShader.Uniform1f(screenWidthShadowLoc,float(self.width())) self.circleShadowShader.Uniform1f(screenHeightShadowLoc,float(self.height())) if shaders_on and hasattr(self,"shader") and self.shader: self.shader.turnOn() if self.doAmbient and shaders_on and hasattr(self,"ssaoShader") and self.ssaoShader: # Render depth to texture self.shaders_on = False self.offScreenBufferDepth.bind() reqW = self.offScreenBufferDepth.width() reqH = self.offScreenBufferDepth.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h # FIXME - Do something in render loop about lines, etc. (like with shadows). self.inAmbient = True #print "Call resizeGLMain ambient 1" self.resizeGLMain(reqW,reqH,ratio) self.paintGL2() self.inAmbient = False self.offScreenBufferDepth.release() # Do SSAO step, draw onto quad. self.offScreenBufferSSAO.bind() reqW = self.offScreenBufferSSAO.width() reqH = self.offScreenBufferSSAO.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h #print "Call resizeGLMain ambient 2" self.resizeGLMain(reqW,reqH,ratio) depthMapLoc = self.ssaoShader.getUniformLocation("depthMap") rotateMapLoc = self.ssaoShader.getUniformLocation("rotateMap") screenWidthLoc = self.ssaoShader.getUniformLocation("screenWidth") screenHeightLoc = self.ssaoShader.getUniformLocation("screenHeight") self.ssaoShader.Uniform1f(screenWidthLoc,reqW) self.ssaoShader.Uniform1f(screenHeightLoc,reqH) self.ssaoShader.Uniform1i(depthMapLoc,3) self.ssaoShader.Uniform1i(rotateMapLoc,2) zNearLoc = self.ssaoShader.getUniformLocation("zNear") zFarLoc = self.ssaoShader.getUniformLocation("zFar") radiusLoc = self.ssaoShader.getUniformLocation("radius") attBiasLoc = self.ssaoShader.getUniformLocation("attBias") attScaleLoc = self.ssaoShader.getUniformLocation("attScale") self.ssaoShader.Uniform1f(zNearLoc,self.ambientOcclusionZNear*self.RADIUS/60.) self.ssaoShader.Uniform1f(zFarLoc,self.ambientOcclusionZFar*self.RADIUS/60.) self.ssaoShader.Uniform1f(radiusLoc,self.ambientOcclusionRadius) self.ssaoShader.Uniform1f(attBiasLoc,self.ambientOcclusionBias) self.ssaoShader.Uniform1f(attScaleLoc,self.ambientOcclusionScale) self.ssaoShader.turnOn() opengl.SetMyTextureUnit(opengl.GL_TEXTURE3); opengl.glEnable(opengl.GL_TEXTURE_2D) texture = self.offScreenBufferDepth.texture() opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.SetMyTextureUnit(opengl.GL_TEXTURE2); opengl.glEnable(opengl.GL_TEXTURE_2D) if not hasattr(self,"rotateMap"): self.makeCurrent() im = QtGui.QImage(os.path.join(os.environ["CCP4MG"],"shaders","rotate.png")) self.rotateMap = self.bindTexture(im) opengl.glBindTexture(opengl.GL_TEXTURE_2D,self.rotateMap) opengl.glTexParameterf( opengl.GL_TEXTURE_2D, opengl.GL_TEXTURE_WRAP_S, opengl.GL_REPEAT ); opengl.glTexParameterf( opengl.GL_TEXTURE_2D, opengl.GL_TEXTURE_WRAP_T, opengl.GL_REPEAT ); opengl.SetMyTextureUnit(opengl.GL_TEXTURE0); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glDisable(opengl.GL_TEXTURE_2D) #self.resizeGLMain(w,h,ratio) opengl.glMatrixMode(opengl.GL_MODELVIEW); opengl.glTranslated(-self.rpos[0],-self.rpos[1],-self.rpos[2]) quat = pygl_coord.Quat(self.quat) extraQuat = pygl_coord.Quat(self.extra_quat) quat.postMult(extraQuat) glrotmat = quat.getMatrix().to_dp() opengl.glMultMatrixd(glrotmat) opengl.delcdp(glrotmat) # FIXME, do not know why, but this helps us zoom in closer and still have AO work. opengl.glTranslatef(0,0,240) texture = self.offScreenBufferDepth.texture() opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.ssaoShader.turnOff() self.offScreenBufferSSAO.release() texture = self.offScreenBufferSSAO.texture() # Blur with FBO Ping-pong. # ping ... self.offScreenBufferBlur.bind() self.blurXShader.turnOn() opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.blurXShader.turnOff() self.offScreenBufferBlur.release() # ... pong. texture = self.offScreenBufferBlur.texture() self.offScreenBufferSSAO.bind() self.blurYShader.turnOn() #self.resizeGLMain(reqW,reqH,1./ratio) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*ratio*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*ratio*glslMult,12*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*ratio*glslMult,12*glslMult,-200) opengl.glEnd() self.blurYShader.turnOff() self.offScreenBufferSSAO.release() texture = self.offScreenBufferSSAO.texture() # Do normal render with SSAO term set as texture... if shaders_on and hasattr(self,"shader") and self.shader: self.shader.turnOn() self.shader.Uniform1f(ssaoOnLoc,True) self.circleShader.Uniform1f(ssaoOnLocCircle,True) w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h SSAOMapLoc = self.shader.getUniformLocation("SSAOMap") screenWidthLoc = self.shader.getUniformLocation("screenWidth") screenHeightLoc = self.shader.getUniformLocation("screenHeight") self.shader.Uniform1i(SSAOMapLoc,3) self.shader.Uniform1f(screenWidthLoc,float(self.width())) self.shader.Uniform1f(screenHeightLoc,float(self.height())) SSAOMapLoc = self.circleShader.getUniformLocation("SSAOMap") screenWidthLoc = self.circleShader.getUniformLocation("screenWidth") screenHeightLoc = self.circleShader.getUniformLocation("screenHeight") self.circleShader.Uniform1i(SSAOMapLoc,3) self.circleShader.Uniform1f(screenWidthLoc,float(self.width())) self.circleShader.Uniform1f(screenHeightLoc,float(self.height())) opengl.SetMyTextureUnit(opengl.GL_TEXTURE3); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) #print "Call resizeGLMain ambient 3", w,h self.resizeGLMain(w,h,ratio) """ self.use_pbuffer = use_pbuffer if self.use_pbuffer: self.makeCurrent() """ self.shaders_on = shaders_on #self.paintGL2() #return if True and (self.doMirror or self.doShadow): #print self.rpos if self.doShadow: self.offScreenBufferShadow.bind() elif self.doMirror: self.offScreenBuffer.bind() shaders_on = self.shaders_on self.shaders_on = False if self.doMirror: rotX = pygl_coord.Quat(1.0,0.0,0.0,1,-90.0) oldQuat = pygl_coord.Quat(self.quat) newQuat = pygl_coord.Quat(self.quat) newQuat.postMult(rotX) self.quat = newQuat if shaders_on and self.doShadow: self.shaders_on = False if hasattr(self,"shader") and self.shader: self.shader.turnOff() rotX = pygl_coord.Quat(1.0,0.0,0.0,1,0.0) extraQuat = pygl_coord.Quat(self.extra_quat) if hasattr(self,"lights"): zprime = pygl_coord.Cartesian(self.lights[0].position) zprime.normalize() zorig = extraQuat.getInvMatrix()*pygl_coord.Cartesian(0,0,1) dp = pygl_coord.Cartesian.DotProduct(zprime,zorig) #print dp angle = math.acos(dp)*180/math.pi #print angle if (1.0-dp)>1e-6: axis = pygl_coord.Cartesian.CrossProduct(zprime,zorig) axis.normalize() #axis.Print(); print rotX = pygl_coord.Quat(axis.get_x(),axis.get_y(),axis.get_z(),1,angle) oldQuat = pygl_coord.Quat(self.quat) newQuat = pygl_coord.Quat(self.quat) newQuat.postMult(extraQuat) newQuat.postMult(rotX) #opengl.glColorMask(opengl.GL_FALSE, opengl.GL_FALSE, opengl.GL_FALSE, opengl.GL_FALSE) #opengl.glEnable(opengl.GL_CULL_FACE) opengl.glCullFace(opengl.GL_FRONT) self.inShadow = True if self.doShadow: reqW = self.offScreenBufferShadow.width() reqH = self.offScreenBufferShadow.height() elif self.doMirror: reqW = self.offScreenBuffer.width() reqH = self.offScreenBuffer.height() w,h = self.width(),self.height() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h #print "Call resizeGLMain shadow 1" self.resizeGLMain(reqW,reqH,1) if hasattr(self,"shadowShader"): self.shadowShader.turnOn() if self.doShadow: if hasattr(self,"shadowShader"): """ self.setupModelview() glslMult = 60./float(self.RADIUS) cartz0 = pygl_coord.Cartesian(0,0,1) #div0 = (self.NEAR+self.FAR)/2.+glslMult*(self.slab_offset+self.slab_width/2.) cartz1 = pygl_coord.Cartesian(0,0,1) #div1 = -((self.NEAR+self.FAR)/2.+glslMult*(self.slab_offset-self.slab_width/2.)) cartz0 = oldQuat.getMatrix() * (cartz0) #cartz1 = newQuat.getMatrix() * (cartz1) glslMult = 60./float(self.RADIUS) """ # FIXME need to use transformed cartz, not test plane. and why shadowExtent? (or is it just randomly 30ish?) self.circleShadowShader.setClipPlanes(opengl.newfv4(0,0,-1,-self.shadowExtent*0.5-(self.slab_offset-self.slab_width/2.)-0.5),opengl.newfv4(0,0,-1,60)); self.shadowShader.setClipPlanes(opengl.newfv4(0,0,-1,-self.shadowExtent*0.5-(self.slab_offset-self.slab_width/2.)-0.5),opengl.newfv4(0,0,-1,60)); #self.shadowShader.setClipPlanes(opengl.newfv4(cartz0.get_x(),cartz0.get_y(),cartz0.get_z(),div0),opengl.newfv4(cartz1.get_x(),cartz1.get_y(),cartz1.get_z(),div1)); # FIXME need to be set for shader lang version <=1.2 #opengl.glClipPlane(opengl.GL_CLIP_PLANE0,opengl.newdv4(cartz0.get_x(),cartz0.get_y(),cartz0.get_z(),-(self.slab_offset-self.slab_width/2.))) if self.doShadow: self.quat = newQuat self.paintGL2() if hasattr(self,"shadowShader"): self.shadowShader.turnOff() if shaders_on and self.doShadow: opengl.setTextureMatrix() if self.doShadow: self.offScreenBufferShadow.release() elif self.doMirror: self.offScreenBuffer.release() if self.doMirror or (shaders_on and self.doShadow): self.quat = oldQuat self.inShadow = False #print "Call resizeGLMain shadow 2" self.resizeGLMain(w,h,ratio) opengl.glCullFace(opengl.GL_BACK) self.shaders_on = shaders_on opengl.glColorMask(opengl.GL_TRUE, opengl.GL_TRUE, opengl.GL_TRUE, opengl.GL_TRUE) if True and (shaders_on and self.doShadow): if os.environ.has_key("CCP4MG_DEBUG_SHADOWS"): self.offScreenBufferShadow.toImage().save("vsm.png") texture = self.offScreenBufferShadow.texture() #self.offScreenBuffer.toImage().save("vsm.png") opengl.SetMyTextureUnit(opengl.GL_TEXTURE2); # This should not be necessary here, but seems to be. Calling once at init ought to be # enough, but that seems not to work. Getting close.... #if self.shader and hasattr(self.shader,"setSamplerUniforms"): self.shader.setSamplerUniforms() opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.SetMyTextureUnit(opengl.GL_TEXTURE0); opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,0) opengl.glDisable(opengl.GL_TEXTURE_2D) if self.shaders_on and self.shader: self.shader.setShadowState(True) self.circleShader.setShadowState(True) else: if self.shaders_on and self.shader: self.shader.setShadowState(False) self.circleShader.setShadowState(False) if True and (self.doShadow and self.shaders_on and hasattr(self,"shader") and self.shader): self.shader.turnOn() xPixelOffsetLoc = self.shader.getUniformLocation("xPixelOffset") yPixelOffsetLoc = self.shader.getUniformLocation("yPixelOffset") ShadowMapLoc = self.shader.getUniformLocation("ShadowMap") self.shader.Uniform1f(xPixelOffsetLoc,1.0/self.offScreenBufferShadow.width()) self.shader.Uniform1f(yPixelOffsetLoc,1.0/self.offScreenBufferShadow.height()) self.shader.Uniform1i(ShadowMapLoc,2) mw = MAINWINDOW() if mw and hasattr(mw,"roll_timer") and mw.roll_timer.isActive() : shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,0) if True and (self.doShadow and self.shaders_on and hasattr(self,"circleShader") and self.circleShader): self.circleShader.turnOn() xPixelOffsetLoc = self.circleShader.getUniformLocation("xPixelOffset") yPixelOffsetLoc = self.circleShader.getUniformLocation("yPixelOffset") ShadowMapLoc = self.circleShader.getUniformLocation("ShadowMap") self.circleShader.Uniform1f(xPixelOffsetLoc,1.0/self.offScreenBufferShadow.width()) self.circleShader.Uniform1f(yPixelOffsetLoc,1.0/self.offScreenBufferShadow.height()) self.circleShader.Uniform1i(ShadowMapLoc,2) mw = MAINWINDOW() if mw and hasattr(mw,"roll_timer") and mw.roll_timer.isActive() : shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,0) self.use_pbuffer = use_pbuffer self.paintGL2() if not self.use_pbuffer and self.doMirror: opengl.glMatrixMode(opengl.GL_MODELVIEW); opengl.glTranslated(-self.rpos[0],-self.rpos[1],-self.rpos[2]) quat = pygl_coord.Quat(self.quat) glrotmat = quat.getMatrix().to_dp() opengl.glMultMatrixd(glrotmat) opengl.delcdp(glrotmat) opengl.glTranslatef(0,0,0) if self.offScreenBufferTexture and QtOpenGL.QGLFramebufferObject.hasOpenGLFramebufferBlit(): rect = QtCore.QRect(0,0,self.offScreenBuffer.width(),self.offScreenBuffer.height()) QtOpenGL.QGLFramebufferObject.blitFramebuffer(self.offScreenBufferTexture, rect, self.offScreenBuffer, rect); texture = self.offScreenBufferTexture.texture() else: texture = self.offScreenBuffer.texture() opengl.glEnable(opengl.GL_TEXTURE_2D) opengl.glBindTexture(opengl.GL_TEXTURE_2D,texture) opengl.glDepthFunc(opengl.GL_LESS); opengl.glEnable(opengl.GL_DEPTH_TEST) glslMult = float(self.RADIUS)/60. opengl.glNormal3f(1,1,1) opengl.glColor4f(1,1,1,1) opengl.glBegin(opengl.GL_QUADS) opengl.glTexCoord2f(0,1) opengl.glVertex3f(-12*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,1) opengl.glVertex3f(12*glslMult,-12*glslMult,-200) opengl.glTexCoord2f(1,0) opengl.glVertex3f(12*glslMult,-2*glslMult,-200) opengl.glTexCoord2f(0,0) opengl.glVertex3f(-12*glslMult,-2*glslMult,-200) opengl.glEnd() def setAmbientOcclusionState(self,state=0): if type(state) == tuple: dum,state = state self.doAmbient = state w,h = self.width(),self.height() self.resizeGL(w,h) self.emit(QtCore.SIGNAL("AmbientOcclusionStateChanged"), (self,state)) def setOutlineState(self,state=0): self.doOutline = state w,h = self.width(),self.height() self.resizeGL(w,h) def setShadowState(self,state=0,quality=2): if type(state) == tuple: dum,state,quality = state self.doShadow = state if self.shaders_on and self.shader: self.shader.setShadowState(bool(state)) shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,quality) if self.shaders_on and self.circleShader: self.circleShader.setShadowState(bool(state)) shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,quality) w,h = self.width(),self.height() self.resizeGL(w,h) self.emit(QtCore.SIGNAL("ShadowStateChanged"), (self,state,quality)) def paintGL2(self): if self.use_pbuffer: self.BindOffScreenBuffer() """ err = opengl.glGetError() if err: print "Error at start of paint GL", err; sys.stdout.flush() """ smooth_line = 1 try: smooth_line = PM("render_quality").getparams()["smooth_line"] except: pass if hasattr(self,"shader") and hasattr(self.shader,"turnOff") and callable(self.shader.turnOff): self.shader.turnOff() self.setupZalmanStencil(self.width(),self.height()) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT) if self.doStereo and (self.stereoAvailable or self.doZalmanStereo): import MGApplication stereo_mode = MGApplication.GetMainWindow().stereo_mode if stereo_mode == 'ROTATION': self.left_quat = pygl_coord.Quat(0.0,1.0,0.0,1,0.5*MGApplication.GetMainWindow().stereo_rotation_angle) self.right_quat = pygl_coord.Quat(0.0,1.0,0.0,1,-0.5*MGApplication.GetMainWindow().stereo_rotation_angle) self.left_furtherMatrix = None self.right_furtherMatrix = None else: self.left_quat = None self.right_quat = None if self.stereo_shear_separation != MGApplication.GetMainWindow().stereo_shear_separation: self.stereo_shear_separation = MGApplication.GetMainWindow().stereo_shear_separation shear_plus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, self.stereo_shear_separation,0,1,0, 0,0,0,1]) shear_minus = pygl_coord.matrix(4,4,[1,0,0,0, 0,1,0,0, -self.stereo_shear_separation,0,1,0, 0,0,0,1]) self.right_furtherMatrix = shear_plus.to_dp() self.left_furtherMatrix = shear_minus.to_dp() if self.doZalmanStereo: opengl.glEnable(opengl.GL_STENCIL_TEST); opengl.glStencilFunc(opengl.GL_EQUAL, 1, 1); opengl.glStencilOp(opengl.GL_KEEP, opengl.GL_KEEP, opengl.GL_KEEP); if not self.doZalmanStereo: opengl.glDrawBuffer(opengl.GL_BACK_LEFT) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) self.setupModelview(furtherQuat=self.left_quat,furtherMatrix=self.left_furtherMatrix) self.paintGLMain(smooth_line) if self.doZalmanStereo: opengl.glStencilFunc(opengl.GL_EQUAL, 0, 1); opengl.glStencilOp(opengl.GL_KEEP, opengl.GL_KEEP, opengl.GL_KEEP); if not self.doZalmanStereo: opengl.glDrawBuffer(opengl.GL_BACK_RIGHT) opengl.glClear(opengl.GL_COLOR_BUFFER_BIT | opengl.GL_DEPTH_BUFFER_BIT ) self.setupModelview(furtherQuat=self.right_quat,furtherMatrix=self.right_furtherMatrix) self.paintGLMain(smooth_line) opengl.glDisable(opengl.GL_STENCIL_TEST); else: self.furtherMatrix=None self.furtherQuat=None self.setupModelview() self.paintGLMain(smooth_line) """ err = opengl.glGetError() if err: print "Error at end of paint GL", err; sys.stdout.flush() """ def paintGLMain(self,smooth_line=1): if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.paintGLMain(self,smooth_line) self.showFPS() def showFPS(self): message = "" if self.show_fps: self.nframes = self.nframes + 1 t = time.time() if t - self.previous_time > 1: fps = (self.nframes-self.previous_frames)/( time.time()-self.previous_time) fps_text = ( "%4.0f" ) % fps self.previous_frames = self.nframes self.previous_time = t message = message + "framerate:"+fps_text+" " self.current_fps_text = fps_text else: message = message + "framerate:"+self.current_fps_text+" " self.showMessage(message) def setupZalmanStencil(self, w, h): if self.use_pbuffer: self.BindOffScreenBuffer() if self.doStereo and self.doZalmanStereo: opengl.glPushAttrib(opengl.GL_ENABLE_BIT) opengl.glMatrixMode(opengl.GL_PROJECTION); opengl.glPushMatrix(); opengl.glLoadIdentity(); opengl.glOrtho(0,w,0,h,-10.0,10.0); opengl.glMatrixMode(opengl.GL_MODELVIEW); opengl.glPushMatrix(); opengl.glLoadIdentity(); opengl.glTranslatef(0.33,0.33,0.0); opengl.glDisable(opengl.GL_STENCIL_TEST); opengl.glDisable(opengl.GL_ALPHA_TEST); opengl.glDisable(opengl.GL_LIGHTING); opengl.glDisable(opengl.GL_FOG); opengl.glDisable(opengl.GL_NORMALIZE); opengl.glDisable(opengl.GL_DEPTH_TEST); opengl.glDisable(opengl.GL_COLOR_MATERIAL); opengl.glDisable(opengl.GL_LINE_SMOOTH); opengl.glDisable(opengl.GL_DITHER); opengl.glDisable(opengl.GL_BLEND); opengl.glShadeModel(opengl.GL_SMOOTH); opengl.glDisable(0x809D); #/* GL_MULTISAMPLE_ARB */ opengl.glClearStencil(0); opengl.glColorMask(False,False,False,False); opengl.glDepthMask(False); opengl.glClear(opengl.GL_STENCIL_BUFFER_BIT); opengl.glEnable(opengl.GL_STENCIL_TEST); opengl.glStencilFunc(opengl.GL_ALWAYS, 1, 1); opengl.glStencilOp(opengl.GL_KEEP, opengl.GL_KEEP, opengl.GL_REPLACE); opengl.glLineWidth(1.0); opengl.glBegin(opengl.GL_LINES); for y in range(0,h,2): opengl.glVertex2i(0,y); opengl.glVertex2i(w,y); opengl.glEnd() opengl.glColorMask(True,True,True,True); opengl.glDepthMask(True); opengl.glMatrixMode(opengl.GL_MODELVIEW); opengl.glPopMatrix(); opengl.glMatrixMode(opengl.GL_PROJECTION); opengl.glPopMatrix(); opengl.glPopAttrib() def resizeGL(self, w, h): if not QtOpenGL.QGLFramebufferObject.hasOpenGLFramebufferObjects (): self.doMirror = False self.doShadow = False if QtOpenGL.QGLFramebufferObject.hasOpenGLFramebufferBlit() and self.doMirror: self.offScreenBuffer = self.offScreenBufferMirror self.offScreenBufferTexture = self.offScreenBufferTextureMirror elif self.doAmbient or self.doOutline: self.offScreenBuffer = self.offScreenBufferDepth self.offScreenBufferTexture = None #self.doShadow = False elif self.doShadow: self.offScreenBuffer = self.offScreenBufferShadow self.offScreenBufferTexture = None else: self.offScreenBuffer = None #self.offScreenBufferOther if self.use_pbuffer: self.BindOffScreenBuffer() if h == 0: h = 1 if w == 0: w = 1 ratio = 1.0*w / h if not self.use_pbuffer: self.setupZalmanStencil(w,h) if not self.use_pbuffer and (self.doMirror or self.doShadow): self.offScreenBuffer.bind() self.resizeGLMain(w,h,ratio) if not self.use_pbuffer and (self.doMirror or self.doShadow): self.offScreenBuffer.release() self.resizeGLMain(w,h,ratio) def resizeGLMain(self, w, h,ratio): opengl.glMatrixMode(opengl.GL_PROJECTION); opengl.glLoadIdentity(); if self.use_pbuffer: print "use_pbuffer"; sys.stdout.flush() if self.inShadow: print "resizeGLMain shadow" opengl.glOrtho(-self.shadowExtent/2.,self.shadowExtent/2.,-self.shadowExtent/2.,self.shadowExtent/2.,0.0001,self.shadowExtent); elif self.inAmbient: print "resizeGLMain ambient" opengl.glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,470,530); else: print "resizeGLMain normal" ratio = 1.0*self.pbuffer.width()/self.pbuffer.height() opengl.glViewport(0, 0, self.pbuffer.width(), self.pbuffer.height()); pbuffer_scale = float(self.pbuffer.height()-2*self.fbo_offset)/self.req_pbuffer_size.height() opengl.glOrtho(-self.viewsize*ratio*pbuffer_scale,self.viewsize*ratio*pbuffer_scale,-self.viewsize*pbuffer_scale,self.viewsize*pbuffer_scale,self.NEAR,self.FAR); else: opengl.glViewport(0, 0, w, h); if self.inShadow: opengl.glOrtho(-self.shadowExtent/2.,self.shadowExtent/2.,-self.shadowExtent/2.,self.shadowExtent/2.,0.0001,self.shadowExtent); elif self.inAmbient: # FIXME Numbers seem reasonable until we get in close. opengl.glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,0.0001,self.FAR); # FIXME The following is much better for outline depth edge detection #opengl.glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,500-.5*self.shadowExtent,500+.5*self.shadowExtent); else: opengl.glOrtho(-self.viewsize*ratio,self.viewsize*ratio,-self.viewsize,self.viewsize,self.NEAR,self.FAR); opengl.glMatrixMode(opengl.GL_MODELVIEW) cprim.BillBoardText().SetMatrices() self.emit(QtCore.SIGNAL("SizeChanged"), (self.size())) def wheelEvent(self, event): if sys.platform == "darwin": factor = 1. + (event.delta()/5000.) else: factor = 1. + (event.delta()/500.) self.RADIUS = self.RADIUS * factor if self.RADIUS < 1: self.RADIUS = 1 self.emit(QtCore.SIGNAL("ZoomChanged"), (self)) self.updateGL() self.emit(QtCore.SIGNAL("ViewChanged"),(self)) def lrudqaopnmkey_handler(self): dx = 0 dy = 0 dz = 0 if self.qkey_timer.isActive(): dx -= 1 if self.akey_timer.isActive(): dx += 1 if self.okey_timer.isActive(): dy -= 1 if self.pkey_timer.isActive(): dy += 1 if self.mkey_timer.isActive(): dz -= 1 if self.nkey_timer.isActive(): dz += 1 if not self.keys_down[QtCore.Qt.Key_Shift]: dx *= 0.1 dy *= 0.1 dz *= 0.1 #self.setRotation(dx,dy,dz) cart = self.extra_quat.getInvMatrix()*pygl_coord.Cartesian(dx,dy,dz) dx, dy,dz = cart.get_x(), cart.get_y(), cart.get_z() rotQ = pygl_coord.Quat(dx,dy,dz,0) self.quat.postMult(rotQ) xshift = 0 yshift = 0 zshift = 0 if self.rightkey_timer.isActive(): xshift += 5 if self.leftkey_timer.isActive(): xshift -= 5 if self.upkey_timer.isActive(): yshift -= 5 if self.downkey_timer.isActive(): yshift += 5 if not self.keys_down[QtCore.Qt.Key_Shift]: xshift *= 0.1 yshift *= 0.1 self.rpos = self.movexyz(self.rpos,[xshift,yshift,0]) self.SetupSymmetry() self.updateGL() self.emit(QtCore.SIGNAL("QuatChanged"),(self)) self.emit(QtCore.SIGNAL("PositionChanged"),(self)) def pluskey_handler(self): self.handleZoom(None,0,.4) self.updateGL() def minuskey_handler(self): self.handleZoom(None,0,-.4) self.updateGL() """ def toggleRecording(self): if self.recording: self.record_timer.stop() ffmpeg_wrapper.CloseMovie() self.recording = 0 self.parent().record_action.setText(self.tr('Start &recording')) else: win_w = self.size().width() win_h = self.size().height() ffmpeg_wrapper.OpenMovie(win_w,win_h,"silly.mpg") self.record_timer.start(1) self.recording = 1 self.parent().record_action.setText(self.tr('Stop &recording')) def record_handler(self): iinfo = self.screenshot() iinfo.invert() yuv = iinfo.getyuv() ffmpeg_wrapper.AddYUVMovieFrame(yuv) self.updateGL() del iinfo """ def roll_handler(self): rotQ = pygl_coord.Quat(self.roll_quat[0],self.roll_quat[1],self.roll_quat[2],self.roll_quat[3]) self.quat.postMult(rotQ) self.updateGL() def keyPressEvent(self, event): if event.isAutoRepeat(): return if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,0) self.updateGL() if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,0) self.updateGL() self.keys_down[event.key()]=1 if event.key() == QtCore.Qt.Key_Escape: children = MAINWINDOW().findChildren(QtGui.QAction,"fullscreen") for child in children: child.setChecked(False) MAINWINDOW().toggleFullscreen() break if event.key() == QtCore.Qt.Key_Q: self.qkey_timer.start(5) if event.key() == QtCore.Qt.Key_A: self.akey_timer.start(5) if event.key() == QtCore.Qt.Key_O: self.okey_timer.start(5) if event.key() == QtCore.Qt.Key_Minus: self.minuskey_timer.start(5) if event.key() == QtCore.Qt.Key_Plus: self.pluskey_timer.start(5) if event.key() == QtCore.Qt.Key_P: self.pkey_timer.start(5) if event.key() == QtCore.Qt.Key_N: self.nkey_timer.start(5) if event.key() == QtCore.Qt.Key_M: self.mkey_timer.start(5) if event.key() == QtCore.Qt.Key_Left: self.leftkey_timer.start(5) if event.key() == QtCore.Qt.Key_Right: self.rightkey_timer.start(5) if event.key() == QtCore.Qt.Key_Up: self.upkey_timer.start(5) if event.key() == QtCore.Qt.Key_Down: self.downkey_timer.start(5) def keyReleaseEvent(self, event): if event.isAutoRepeat(): return keysActive = False if (self.qkey_timer.isActive()^ event.key() == QtCore.Qt.Key_Q)\ or (self.akey_timer.isActive()^ event.key() == QtCore.Qt.Key_A)\ or (self.okey_timer.isActive()^ event.key() == QtCore.Qt.Key_O)\ or (self.pkey_timer.isActive()^ event.key() == QtCore.Qt.Key_P)\ or (self.nkey_timer.isActive()^ event.key() == QtCore.Qt.Key_N)\ or (self.mkey_timer.isActive()^ event.key() == QtCore.Qt.Key_M)\ or (self.rightkey_timer.isActive()^ event.key() == QtCore.Qt.Key_Right)\ or (self.leftkey_timer.isActive()^ event.key() == QtCore.Qt.Key_Left)\ or (self.upkey_timer.isActive()^ event.key() == QtCore.Qt.Key_Up)\ or (self.downkey_timer.isActive()^ event.key() == QtCore.Qt.Key_Down): keysActive = True if not keysActive and self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,2) if not keysActive and self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,2) self.updateGL() self.keys_down[event.key()]=0 if event.key() == QtCore.Qt.Key_Q: self.qkey_timer.stop() if event.key() == QtCore.Qt.Key_A: self.akey_timer.stop() if event.key() == QtCore.Qt.Key_O: self.okey_timer.stop() if event.key() == QtCore.Qt.Key_Plus: self.pluskey_timer.stop() if event.key() == QtCore.Qt.Key_Minus: self.minuskey_timer.stop() if event.key() == QtCore.Qt.Key_P: self.pkey_timer.stop() if event.key() == QtCore.Qt.Key_N: self.nkey_timer.stop() if event.key() == QtCore.Qt.Key_M: self.mkey_timer.stop() if event.key() == QtCore.Qt.Key_Left: self.leftkey_timer.stop() if event.key() == QtCore.Qt.Key_Right: self.rightkey_timer.stop() if event.key() == QtCore.Qt.Key_Up: self.upkey_timer.stop() if event.key() == QtCore.Qt.Key_Down: self.downkey_timer.stop() if event.key() != QtCore.Qt.Key_Shift and event.key()!= QtCore.Qt.Key_Control and event.key()!= QtCore.Qt.Key_Alt and event.key()!= QtCore.Qt.Key_Meta: self.emit(QtCore.SIGNAL("ViewChanged"),(self)) def DrawInThread(self): self.go.draw() def mouseDoubleClickEvent(self, event): self.lastEventType = event.type() self.setupModelview(self.furtherMatrix,self.furtherQuat) pickevent = MGPickEvent.MGPickEvent(self,event) self.doubleClickHandler(pickevent) def aboutToHideHandler(self): self.showing_context_menu = False def aboutToShowHandler(self): if self.showing_context_menu == False: self.showing_context_menu = True else: pass #print 'aboutToShowHandler showing_context_menu is true' #return self.setupModelview(self.furtherMatrix,self.furtherQuat) if self.contextMenuPickEvent: self.contextMenuHandler(self.contextMenuPickEvent) del self.contextMenuPickEvent self.contextMenuPickEvent = None def getLeftClickHandler(self): return self.leftClickHandler def setLeftClickHandler(self,handler): self.leftClickHandler = handler def getDoubleClickHandler(self): return self.doubleClickHandler def setDoubleClickHandler(self,handler): self.doubleClickHandler = handler def setContextMenuHandler(self,handler): self.contextMenuHandler = handler def mousePressEvent(self, event): if self.useCootMouseBindings and self.keys_down[QtCore.Qt.Key_C]==1: print "contextMenuEvent",event.type() self.keys_down[QtCore.Qt.Key_C] = 0 self.setupModelview(self.furtherMatrix,self.furtherQuat) if hasattr(self,"context_menu"): self.lastPos = QtCore.QPoint(event.pos()) self.contextMenuPickEvent = MGPickEvent.MGPickEvent(self,event) self.context_menu.exec_(self.mapToGlobal(self.lastPos)) del self.contextMenuPickEvent self.contextMenuPickEvent = None event.accept() else: event.ignore() return self.lastEventType = event.type() #self.emit(QtCore.SIGNAL("mousepress"),(event,self)) self.mousePressEvent_main(event,1) def mousePressEvent_main(self, event,real_event=0): #print "mousePressEvent_main",event.type() # This method was previously handling context menu event self.lastPos = QtCore.QPoint(event.pos()) self.mouseDownPos = QtCore.QPoint(event.pos()) def contextMenuEvent(self,event): if self.useCootMouseBindings: event.accept() return self.setupModelview(self.furtherMatrix,self.furtherQuat) if hasattr(self,"context_menu"): self.lastPos = QtCore.QPoint(event.pos()) self.contextMenuPickEvent = MGPickEvent.MGPickEvent(self,event) self.context_menu.exec_(self.mapToGlobal(self.lastPos)) del self.contextMenuPickEvent self.contextMenuPickEvent = None event.accept() else: event.ignore() def mouseReleaseEvent(self, event): if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,2) self.updateGL() if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,2) self.updateGL() self.mouseReleaseEvent_main(event,1) def mouseReleaseEvent_main(self, event,real_event=0): if self.useCootMouseBindings and int(event.button()) == 4 and self.lastEventType != QtCore.QEvent.MouseMove: self.lastEventType = event.type() self.setupModelview(self.furtherMatrix,self.furtherQuat) pickevent = MGPickEvent.MGPickEvent(self,event) self.doubleClickHandler(pickevent) if self.lastEventType==QtCore.QEvent.MouseButtonDblClick: return self.setupModelview(self.furtherMatrix,self.furtherQuat) moved = '' curPos = QtCore.QPoint(event.pos()) #print "self.lastPos",self.mouseDownPos.x(),self.mouseDownPos.y(),curPos.x(),curPos.y() left = event.buttons() & QtCore.Qt.LeftButton and not event.modifiers()&QtCore.Qt.AltModifier and not event.modifiers()&QtCore.Qt.ControlModifier and not event.modifiers()&QtCore.Qt.MetaModifier # Weird -- 'if left and real_event' does not work if left!=None and real_event: if abs(self.mouseDownPos.x()-curPos.x())>2 or \ abs(self.mouseDownPos.y()-curPos.y())>2: self.emit(QtCore.SIGNAL("ViewChanged"),(self)) else: pickEvent = MGPickEvent.MGPickEvent(self,event) self.leftClickHandler(pickEvent) del pickEvent def setMouseBindings(self,bindings={}): # These are the 'local' handlers handlers = { 'rotate-xy' : self.handleRotateXY, 'rotate-z' : self.handleRotateZ, 'translate-xy' : self.handleTranslateXY, 'translate-z' : self.handleTranslateZ , 'object-rotate-xy' : self.handleRotateObjectXY, 'object-rotate-z' : self.handleRotateObjectZ, 'object-translate-xy' : self.handleTranslateObjectXY, 'object-translate-z' : self.handleTranslateObjectZ, 'zoom' : self.handleZoom, 'clip-width' : self.handleClipping } button_map = { 'left' : QtCore.Qt.LeftButton, 'middle' : QtCore.Qt.MidButton, 'right' : QtCore.Qt.RightButton } key_map = { ' ': 'no_key','a': QtCore.Qt.Key_A,'b': QtCore.Qt.Key_B,'c': QtCore.Qt.Key_C,'d': QtCore.Qt.Key_D,'e': QtCore.Qt.Key_E,'f': QtCore.Qt.Key_F,'g': QtCore.Qt.Key_G,'h': QtCore.Qt.Key_H,'i': QtCore.Qt.Key_I,'j': QtCore.Qt.Key_J,'k': QtCore.Qt.Key_K,'l': QtCore.Qt.Key_L,'m': QtCore.Qt.Key_M,'n': QtCore.Qt.Key_N,'o': QtCore.Qt.Key_O,'p': QtCore.Qt.Key_P,'q': QtCore.Qt.Key_Q,'r': QtCore.Qt.Key_R,'s': QtCore.Qt.Key_S,'t': QtCore.Qt.Key_T,'u': QtCore.Qt.Key_U,'v': QtCore.Qt.Key_V,'w': QtCore.Qt.Key_W,'x': QtCore.Qt.Key_X,'y': QtCore.Qt.Key_Y,'z': QtCore.Qt.Key_Z } self.mouseMoveHandlers = { QtCore.Qt.LeftButton : {}, QtCore.Qt.MidButton : {}, QtCore.Qt.RightButton : {} } for handler,defn in bindings.items(): if handler == "coot_bindings": self.useCootMouseBindings = defn["coot_bindings"] elif hasattr(defn,"__getitem__"): h1 = self.mouseMoveHandlers[button_map[defn['mouse_button']]] if defn.get('shift',0): if defn.get('alt',0): if defn.get('ctrl',0): mod = QtCore.Qt.ShiftModifier | QtCore.Qt.AltModifier | QtCore.Qt.ControlModifier else: mod = QtCore.Qt.ShiftModifier | QtCore.Qt.AltModifier else: mod = QtCore.Qt.ShiftModifier elif defn.get('alt',0): if defn.get('ctrl',0): mod = QtCore.Qt.AltModifier | QtCore.Qt.ControlModifier else: mod = QtCore.Qt.AltModifier elif defn.get('ctrl',0): mod = QtCore.Qt.ControlModifier else: mod = QtCore.Qt.NoModifier if not h1.has_key(mod): h1[mod] = {} h2 = h1[mod] key = key_map.get(defn['key'],'') if key: if handlers.has_key(handler): h2[key] = handlers[handler] else: h2[key] = handler #print "setMouseBindings",mod,key,handler #print "self.mouseMoveHandlers",self.mouseMoveHandlers def removeMouseBindings(self): self.mouseMoveHandlers = {} def setDefaultMouseBindings(self): # initialise mouse bindings import MouseBindings self.setMouseBindings ( MouseBindings.DEFAULT ) # ------------------------------------------------------------ # The following methods will called by object/application # that is being transformed following the "TransformObject" signal # def transformDelta(self): return self.transform_delta def transformDeltaMode(self): return self.transform_delta_mode def screenTransform(self): return ( float(self.transform_delta[0])/self.size().width(), float(self.transform_delta[1])/-self.size().height(), float(self.transform_delta[2])/self.size().height() ) def worldTranslate(self): cv1 = self.getxyz(0,0) cv2 = self.getxyz(float(self.transform_delta[0]),float(self.transform_delta[1])) diffxyz = cv2[0]-cv1[0] return (diffxyz.get_x(),diffxyz.get_y(),diffxyz.get_z()) def worldRotate(self): dx = self.transform_delta[0] dy = self.transform_delta[1] dz = self.transform_delta[2] #print 'worldRotate',dx,dy,dz #cart = self.extra_quat.getMatrix()*pygl_coord.Cartesian(dx,dy,dz) #dx, dy,dz = cart.get_x(), cart.get_y(), cart.get_z() rotQ = pygl_coord.Quat(dx,dy,dz,0) matx = rotQ.getInvMatrix() return matx def handleTesting(self,event,dx,dy): print "in handleTesting" def handleClipping(self,event,dx,dy): #print 'handleClipping',dx,dy self.slab_width = self.slab_width + float(dy)*0.1 self.emit(QtCore.SIGNAL("SlabChanged"), (self)) self.updateGL() def handleTranslateObjectXY(self,event,dx,dy): self.transform_delta_mode = 'translate' self.transform_delta = (dx,dy,0) self.emit(QtCore.SIGNAL("TransformObject"), (self)) def handleTranslateObjectZ(self,event,dx,dy): self.transform_delta_mode = 'translate' self.transform_delta = (0,0,dy) self.emit(QtCore.SIGNAL("TransformObject"), (self)) def handleRotateObjectXY(self,event,dx,dy): self.transform_delta_mode = 'rotate' self.transform_delta = (dx,dy,0) self.emit(QtCore.SIGNAL("TransformObject"), (self)) def handleRotateObjectZ(self,event,dx,dy): self.transform_delta_mode = 'rotate' self.transform_delta = (0,0,dy) self.emit(QtCore.SIGNAL("TransformObject"), (self)) def handleRotateXYZ(self,event,dx,dy): win_w = self.size().width() win_h = self.size().height() x=event.x() y=event.y() zAcc = 0.3 xyAcc = 0.1 frac_x,frac_y = (x-win_w/2.)/(win_w/2.),(y-win_h/2.)/(win_h/2.) self.setRotationNoUpdate(0,0,zAcc*(-frac_x*dy+frac_y*dx)) self.setRotationNoUpdate(xyAcc*(1.0-abs(frac_x))*dy,xyAcc*(1.0-abs(frac_y))*dx,0) def handleRotateXY(self,event,dx,dy): self.setRotationNoUpdate(dy,dx,0) def handleRotateZ(self,event,dx,dy): win_w = self.size().width() win_h = self.size().height() x=event.x() y=event.y() if xwin_w*2/3: self.setRotationNoUpdate(0,0,-dy) if ywin_h*2/3: self.setRotationNoUpdate(0,0,dx) def handleZoom(self,event,dx,dy): factor = 1. - dy/50. self.RADIUS = self.RADIUS * factor if self.RADIUS < 1: self.RADIUS = 1 self.emit(QtCore.SIGNAL("ZoomChanged"), (self)) def handleTranslateZ(self,event,dx,dy): self.rpos = self.movexyz(self.rpos,[0,0,dy]) self.emit(QtCore.SIGNAL("PositionChanged"),(self)) self.SetupSymmetry() def handleTranslateXY(self,event,dx,dy): dx = dx * 10.0 * float(self.viewsize)/float(self.size().height()) * float(self.RADIUS)/60.0 dy = dy * 10.0 * float(self.viewsize)/float(self.size().height()) * float(self.RADIUS)/60.0 self.rpos = self.movexyz(self.rpos,[dx,dy,0]) self.emit(QtCore.SIGNAL("PositionChanged"),(self)) self.SetupSymmetry() def mouseMoveEvent(self, event): diff = QtCore.QPoint(event.pos()) - self.lastPos #if diff.manhattanLength()<4: return dx = event.x() - self.lastPos.x() dy = event.y() - self.lastPos.y() if (dx==0 and abs(dy)<2) or (abs(dy)<2 and dx==0): return if self.useCootMouseBindings: self.lastEventType = event.type() if int(event.buttons()) == 1: if sys.platform == "darwin" and event.modifiers()&QtCore.Qt.MetaModifier==QtCore.Qt.MetaModifier: self.handleTranslateXY(event,dx,dy) elif sys.platform == "darwin" and event.modifiers()&QtCore.Qt.AltModifier==QtCore.Qt.AltModifier: self.handleTranslateXY(event,dx,dy) elif sys.platform == "darwin" and event.modifiers()&QtCore.Qt.ControlModifier==QtCore.Qt.ControlModifier: self.handleZoom(event,dx,dy) elif sys.platform != "darwin" and event.modifiers()&QtCore.Qt.ControlModifier==QtCore.Qt.ControlModifier: self.handleTranslateXY(event,dx,dy) else: self.handleRotateXYZ(event,dx,dy) elif int(event.buttons()) == 2: if sys.platform == "darwin" and event.modifiers()&QtCore.Qt.MetaModifier==QtCore.Qt.MetaModifier: self.handleTranslateZ(event,dx,dy) elif sys.platform != "darwin" and event.modifiers()&QtCore.Qt.ControlModifier==QtCore.Qt.ControlModifier: self.handleTranslateZ(event,dx,dy) else: zoomAcc = 0.2 self.handleZoom(event,zoomAcc*dx,zoomAcc*dy) elif int(event.buttons()) == 4: self.handleTranslateXY(event,dx,dy) else: # Make alt-button on trackpad behave like middle button on Mac. # Sensible, or do we actually want alt in preferences? if sys.platform == 'darwin': if event.button()==0: if event.modifiers()&QtCore.Qt.AltModifier==QtCore.Qt.AltModifier: mods = event.modifiers() mods ^= QtCore.Qt.AltModifier newEvent = QtGui.QMouseEvent(QtCore.QEvent.MouseMove,event.pos(),QtCore.Qt.MidButton,QtCore.Qt.MidButton,mods) event = newEvent h1 = self.mouseMoveHandlers.get(int(event.buttons()),{}) #print "h1",int(event.buttons()),h1 if not h1: return h2 = h1.get(int(event.modifiers()),{}) #print "h2",int(event.modifiers()),h2 if not h2: return handler = '' if isinstance(h2,types.DictType): for key,h3 in h2.items(): if key != 'no_key' and self.keys_down[key]: handler = h3 break # The following line means that we ignore any # key-down that we don't have a binding for and just # apply the 'no_key' binding if not handler: handler = h2.get('no_key','') else: handler = h2 #print "mouseMoveEvent handler",handler if not handler: return handler(event,dx,dy) if self.shaders_on and self.shader and self.doShadow: shadowQuality = self.shader.getUniformLocation("shadowQuality") self.shader.Uniform1i(shadowQuality,0) if self.shaders_on and self.circleShader and self.doShadow: shadowQuality = self.circleShader.getUniformLocation("shadowQuality") self.circleShader.Uniform1i(shadowQuality,0) self.updateGL() self.lastPos = QtCore.QPoint(event.pos()) def movexyz(self,r,dr): dx,dy,dz = self.getdxdydz(dr[0], dr[1], dr[2]) dx = dx/5.0; dy = dy/5.0; dz = dz/5.0; return r[0]+dx, r[1]+dy, r[2]+dz def getxyz(self,x,y): """ Work out world x,y,z at near and far clipping planes. """ #if sys.platform == 'win32': #return CartesianVectorPtr(getxyzc(x,y)) viewport = pygl_coord.inta(4) mvmatrix = pygl_coord.doublea(16) projmatrix = pygl_coord.doublea(16) wx = pygl_coord.doublep() wy = pygl_coord.doublep() wz = pygl_coord.doublep() if self.use_pbuffer: self.BindOffScreenBuffer() opengl.glGetIntegerv(opengl.GL_VIEWPORT,viewport); opengl.glGetDoublev(opengl.GL_PROJECTION_MATRIX,projmatrix); opengl.glGetDoublev(opengl.GL_MODELVIEW_MATRIX,mvmatrix); realy = viewport[3] - y - 1; opengl.gluUnProject(x,realy,0.0,mvmatrix,projmatrix,viewport,wx,wy,wz); cart1 = pygl_coord.Cartesian(wx.value(), wy.value(), wz.value()) opengl.gluUnProject(x,realy,1.0,mvmatrix,projmatrix,viewport,wx,wy,wz); cart2 = pygl_coord.Cartesian(wx.value(), wy.value(), wz.value()) cv = pygl_coord.CartesianVector() cv.append(cart1) cv.append(cart2) del viewport del mvmatrix del projmatrix del wx del wy del wz return cv; def getdxdydz(self,dx,dy,dz): """ Calculate movement in real coordinates corresponding to one in eye coordinates. """ xaxis,yaxis,zaxis = self.xaxis,self.yaxis,self.zaxis dr = [] dr.append(dx*xaxis.get_x()) dr.append(dx*xaxis.get_y()) dr.append(dx*xaxis.get_z()) du = [] du.append(dy*yaxis.get_x()) du.append(dy*yaxis.get_y()) du.append(dy*yaxis.get_z()) df = [] df.append(dz*zaxis.get_x()) df.append(dz*zaxis.get_y()) df.append(dz*zaxis.get_z()) dx = dr[0] + du[0] + df[0] dy = dr[1] + du[1] + df[1] dz = dr[2] + du[2] + df[2] return [dx,dy,dz] def SetGO(self, go_in=None,redraw=0): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.SetGO(self,go_in,redraw) def buildlist(self,go,listid): self.makeCurrent() if self.use_pbuffer: self.BindOffScreenBuffer() MGGLWidgetGL.buildlist(self,go,listid) def showMessage(self,message): if message != "": MAINWINDOW().statusBar().showMessage(message)