def __init__(self, parent=None,enable_timer=False, application_control=True,winid=None): if parent==None : self.qt_parent = EMParentWin(enable_timer) self.myparent=True # we allocated the parent, responsible for cleaning it up else: self.qt_parent=parent self.myparent=False # we did not allocate our parent, so we should not get rid of it QtOpenGL.QGLWidget.__init__(self,self.qt_parent) if self.myparent : self.qt_parent.setup(self) self.inspector = None # a Qt Widget for changing display parameters, setting the data, accessing metadata, etc. self.winid=winid # a 'unique' identifier for the window used to restore locations on the screen self.image_change_count = 0# this is important when the user has more than one display instance of the same image, for instance in e2.py if app = get_application() if app != None and application_control: app.attach_child(self) self.application_control = application_control self.file_name = "" self.disable_inspector = False self.makeCurrent() self.font_renderer = get_3d_font_renderer() if self.font_renderer == None : print("FTGL not initialized. Please make sure you have FTGL installed, and configured for compilation in CMake. If using a binary, please report a problem to [email protected].") sys.exit(1) self.font_renderer.set_face_size(16) self.font_renderer.set_font_mode(FTGLFontMode.TEXTURE) self.busy = False #updateGL() does nothing when self.busy == True
def __init__(self, parent=None,enable_timer=False, application_control=True,winid=None): if parent==None : self.qt_parent = EMParentWin(enable_timer) self.myparent=True # we allocated the parent, responsible for cleaning it up else: self.qt_parent=parent self.myparent=False # we did not allocate our parent, so we should not get rid of it QtOpenGL.QGLWidget.__init__(self,self.qt_parent) if self.myparent : self.qt_parent.setup(self) self.inspector = None # a Qt Widget for changing display parameters, setting the data, accessing metadata, etc. self.winid=winid # a 'unique' identifier for the window used to restore locations on the screen self.image_change_count = 0# this is important when the user has more than one display instance of the same image, for instance in e2.py if app = get_application() if app != None and application_control: app.attach_child(self) self.application_control = application_control self.file_name = "" self.disable_inspector = False self.makeCurrent() self.font_renderer = get_3d_font_renderer() if self.font_renderer == None : print "FTGL not initialized. Please make sure you have FTGL installed, and configured for compilation in CMake. If using a binary, please report a problem to [email protected]." sys.exit(1) self.font_renderer.set_face_size(16) self.font_renderer.set_font_mode(FTGLFontMode.TEXTURE) self.busy = False #updateGL() does nothing when self.busy == True
def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin self.gl_context_parent = EMImageRotorWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setAcceptDrops(True) return self.qt_context_parent
def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin from emimage3d import EMImage3DWidget self.under_qt_control = True self.gl_context_parent = EMImage3DWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setWindowIcon(QtGui.QIcon(get_image_directory() +"single_image_3d.png")) return self.qt_context_parent
src_flags.append(EULER_SPIN) src_flags.append(EULER_XYZ) self.src_strings = [] self.src_map = {} for i in src_flags: self.src_strings.append(str(i)) self.src_map[str(i)] = i def setColors(self,colors,current_color): a = 0 for i in colors: self.cbb.addItem(i) if ( i == current_color): self.cbb.setCurrentIndex(a) a += 1 def set_scale(self,newscale): self.scale.setValue(newscale) # This is just for testing, of course if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = EMGLPlotWidget() window2=EMParentWin(window) window.setInit() window2.show() sys.exit(app.exec_())
class EMGLWidget(QtOpenGL.QGLWidget): """ This class encapsulates the use of the EMParentWin to provide a status bar with a size grip on Mac. It also handles much of the inspector behavior, displays help in a web browser, and provides a self.busy attribute to prevent updateGL() from redrawing before all changes to display parameters are in place. """ def hide(self): if self.qt_parent: self.qt_parent.hide() def resize(self, w, h): if self.qt_parent: QtOpenGL.QGLWidget.resize(self, w, h) if get_platform()=="Darwin" : self.qt_parent.resize(w, h+22) else : self.qt_parent.resize(w+4, h+4) def show(self): if self.qt_parent: self.qt_parent.show() def setWindowTitle(self, title): if self.qt_parent: self.qt_parent.setWindowTitle(title) else: self.setWindowTitle(title) def __init__(self, parent=None,enable_timer=False, application_control=True,winid=None): if parent==None : self.qt_parent = EMParentWin(enable_timer) self.myparent=True # we allocated the parent, responsible for cleaning it up else: self.qt_parent=parent self.myparent=False # we did not allocate our parent, so we should not get rid of it QtOpenGL.QGLWidget.__init__(self,self.qt_parent) if self.myparent : self.qt_parent.setup(self) self.inspector = None # a Qt Widget for changing display parameters, setting the data, accessing metadata, etc. self.winid=winid # a 'unique' identifier for the window used to restore locations on the screen self.image_change_count = 0# this is important when the user has more than one display instance of the same image, for instance in e2.py if app = get_application() if app != None and application_control: app.attach_child(self) self.application_control = application_control self.file_name = "" self.disable_inspector = False self.makeCurrent() self.font_renderer = get_3d_font_renderer() if self.font_renderer == None : print "FTGL not initialized. Please make sure you have FTGL installed, and configured for compilation in CMake. If using a binary, please report a problem to [email protected]." sys.exit(1) self.font_renderer.set_face_size(16) self.font_renderer.set_font_mode(FTGLFontMode.TEXTURE) self.busy = False #updateGL() does nothing when self.busy == True def closeEvent(self, event): if self.inspector: self.inspector.close() QtOpenGL.QGLWidget.closeEvent(self, event) if self.myparent : self.qt_parent.close() self.emit(QtCore.SIGNAL("module_closed")) # this could be a useful signal, especially for something like the selector module, which can potentially show a lot of images but might want to close them all when it is closed event.accept() def display_web_help(self,url="http://blake.bcm.edu/emanwiki/e2display"): try: try: import webbrowser webbrowser.open(url) except: try: test = self.browser except: self.browser = QtWebKit.QWebView() self.browser.load(QtCore.QUrl()) self.browser.resize(800,800) if not self.browser.isVisible(): self.browser.show(url) except: pass def enable_inspector(self,val=True): self.disable_inspector = not val def show_inspector(self,force=0): if self.disable_inspector: return self.emit(QtCore.SIGNAL("inspector_shown")) # debug only app = get_application() if app == None: print "can't show an inspector with having an associated application" if not force and self.inspector==None : return if not self.inspector : self.inspector = self.get_inspector() if self.inspector == None: return # sometimes this happens if not app.child_is_attached(self.inspector): app.attach_child(self.inspector) app.show_specific(self.inspector) def update_inspector_texture(self): if self.inspector != None: self.inspector.update() def updateGL(self): if self.busy: return else: QtOpenGL.QGLWidget.updateGL(self)
class EMGLWidget(QtOpenGL.QGLWidget): """ This class encapsulates the use of the EMParentWin to provide a status bar with a size grip on Mac. It also handles much of the inspector behavior, displays help in a web browser, and provides a self.busy attribute to prevent updateGL() from redrawing before all changes to display parameters are in place. """ def hide(self): if self.qt_parent: self.qt_parent.hide() def resize(self, w, h): if self.qt_parent: QtOpenGL.QGLWidget.resize(self, w, h) if get_platform()=="Darwin" : self.qt_parent.resize(w, h+22) else : self.qt_parent.resize(w+4, h+4) def show(self): if self.qt_parent: self.qt_parent.show() def setWindowTitle(self, title): if self.qt_parent: self.qt_parent.setWindowTitle(title) else: self.setWindowTitle(title) def __init__(self, parent=None,enable_timer=False, application_control=True,winid=None): if parent==None : self.qt_parent = EMParentWin(enable_timer) self.myparent=True # we allocated the parent, responsible for cleaning it up else: self.qt_parent=parent self.myparent=False # we did not allocate our parent, so we should not get rid of it QtOpenGL.QGLWidget.__init__(self,self.qt_parent) if self.myparent : self.qt_parent.setup(self) self.inspector = None # a Qt Widget for changing display parameters, setting the data, accessing metadata, etc. self.winid=winid # a 'unique' identifier for the window used to restore locations on the screen self.image_change_count = 0# this is important when the user has more than one display instance of the same image, for instance in e2.py if app = get_application() if app != None and application_control: app.attach_child(self) self.application_control = application_control self.file_name = "" self.disable_inspector = False self.makeCurrent() self.font_renderer = get_3d_font_renderer() if self.font_renderer == None : print("FTGL not initialized. Please make sure you have FTGL installed, and configured for compilation in CMake. If using a binary, please report a problem to [email protected].") sys.exit(1) self.font_renderer.set_face_size(16) self.font_renderer.set_font_mode(FTGLFontMode.TEXTURE) self.busy = False #updateGL() does nothing when self.busy == True def closeEvent(self, event): if self.inspector: self.inspector.close() QtOpenGL.QGLWidget.closeEvent(self, event) if self.myparent : self.qt_parent.close() self.emit(QtCore.SIGNAL("module_closed")) # this could be a useful signal, especially for something like the selector module, which can potentially show a lot of images but might want to close them all when it is closed event.accept() def display_web_help(self,url="http://blake.bcm.edu/emanwiki/e2display"): try: try: import webbrowser webbrowser.open(url) except: try: test = self.browser except: self.browser = QtWebKit.QWebView() self.browser.load(QtCore.QUrl()) self.browser.resize(800,800) if not self.browser.isVisible(): self.browser.show(url) except: pass def enable_inspector(self,val=True): self.disable_inspector = not val def show_inspector(self,force=0): if self.disable_inspector: return self.emit(QtCore.SIGNAL("inspector_shown")) # debug only app = get_application() if app == None: print("can't show an inspector with having an associated application") if not force and self.inspector==None : return if not self.inspector : self.inspector = self.get_inspector() if self.inspector == None: return # sometimes this happens if not app.child_is_attached(self.inspector): app.attach_child(self.inspector) app.show_specific(self.inspector) def update_inspector_texture(self): if self.inspector != None: self.inspector.update() def updateGL(self): if self.busy: return else: QtOpenGL.QGLWidget.updateGL(self)
class EMImageRotorModule(EMGUIModule): def get_desktop_hint(self): return "rotor" def get_gl_widget(self,qt_context_parent,gl_context_parent): from emfloatingwidgets import EM3DGLWindowOverride if self.gl_widget == None: self.gl_context_parent = gl_context_parent self.qt_context_parent = qt_context_parent self.gl_widget = EM3DGLWindowOverride(self,self.rotor) self.rotor.target_zoom_events_allowed(False) self.rotor.target_translations_allowed(False) return self.gl_widget def __del__(self): for widget in self.rotor.get_widgets(): self.application.deregister_qt_emitter(widget.get_drawable().get_drawable()) def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin self.gl_context_parent = EMImageRotorWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setAcceptDrops(True) return self.qt_context_parent #def get_qt_widget(self): #if self.parent == None: #from emimageutil import EMParentWin #self.gl_parent = EMImageRotorWidget(self) #self.parent = EMParentWin(self.gl_parent) #self.set_gl_parent(self.gl_parent) #return self.parent def __init__(self, data=None,application=None): self.rotor = EMGLRotorWidget(self,15,10,45,EMGLRotorWidget.LEFT_ROTARY) EMGUIModule.__init__(self,ensure_gl_context=True) self.data=None self.initsizeflag = True if data: self.set_data(data) self.widget = EM3DGLWindow(self,self.rotor) self.widget.set_draw_frame(False) self.z_near = 0 self.z_far = 0 self.hud_data = [] # a list of strings to be rendered to the heads up display (hud) self.load_font_renderer() def optimally_resize(self): if isinstance(self.gl_context_parent,EMImageRotorWidget): self.qt_context_parent.resize(*self.get_optimal_size()) else: self.gl_widget.resize(*self.get_optimal_size()) def load_font_renderer(self): try: self.font_renderer = get_3d_font_renderer() self.font_renderer.set_face_size(20) self.font_renderer.set_depth(4) self.font_renderer.set_font_mode(FTGLFontMode.EXTRUDE) # self.font_renderer.set_font_file_name("/usr/share/fonts/dejavu/DejaVuSerif.ttf") self.font_render_mode = EMGUIModule.FTGL except: self.font_render_mode = EMGUIModule.GLUT def set_extra_hud_data(self,hud_data): self.hud_data = hud_data def get_optimal_size(self): lr = self.rotor.get_lr_bt_nf() width = lr[1] - lr[0] height = lr[3] - lr[2] return [width+80,height+20] #self.rotor.set_shapes([],1.01) def context(self): # asking for the OpenGL context from the parent return self.gl_context_parent.context() def emit(self,*args,**kargs): #print "emitting",signal,event self.application.get_qt_emitter(self).emit(*args,**kargs) #if b != None: #elif a != None: #self.application.get_qt_emitter(self).emit(signal,event,a) #else: #self.application.get_qt_emitter(self).emit(signal,event) def set_mouse_mode(self,mode): self.mmode = mode self.rotor.set_mouse_mode(mode) def set_frozen(self,frozen,idx=0): self.rotor.set_frozen(frozen,idx) def set_shapes(self,shapes,shrink,idx=0): self.rotor.set_shapes(shapes,shrink,idx) def register_animatable(self,animatable): self.get_qt_context_parent().register_animatable(animatable) def get_inspector(self): return None def width(self): try: return self.get_parent().width() except: return 0 def height(self): try: return self.get_parent().height() except: return 0 def getImageFileName(self): ''' warning - could return none in some circumstances''' try: return self.gl_widget.getImageFileName() except: return None def set_data(self,data): if data == None or not isinstance(data,list) or len(data)==0: self.data = [] return self.data = data self.rotor.clear_widgets() for d in self.data: w = EM2DGLView(self,d) #w.get_drawable().set_app(self.application) # self.application.register_qt_emitter(w.get_drawable(),self.application.get_qt_emitter(self)) x = EM2DGLWindow(self,w) x.set_width(w.width()) x.set_height(w.height()) self.rotor.add_widget(x) def updateGL(self): try: self.gl_widget.updateGL() except: pass def render(self): if not self.data : return #glLoadIdentity() GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_LIGHTING) lr = self.rotor.get_lr_bt_nf() lrt = lr #lr = self.widget.get_lr_bt_nf() z = self.gl_context_parent.get_depth_for_height(abs(lr[3]-lr[2])) z_near = z-lrt[4] z_trans = 0 z_far = z-lrt[5] if z_near < 0: z_trans = z_near z_near = 0.1 z_far -= z_trans if z_far < 0: z_far = 0.1 # hacking alert if self.z_near != z_near or self.z_far != z_far: self.z_near = z_near self.z_far = z_far if isinstance(self.gl_context_parent,EMImageRotorWidget): self.gl_context_parent.set_near_far(self.z_near,self.z_far) else: print "bug" #FTGL.print_message("hello world",36); #print self.z_near,self.z_far,-self.parent.get_depth_for_height(abs(lr[3]-lr[2]))+z_trans glPushMatrix() glTranslate(0,0,-z) #glTranslate(0,-75,0) # This number is a FIXME issue #FTGL.print_message("hello hello",36); self.widget.draw() glPopMatrix() self.draw_hud() def dragEnterEvent(self,event): pass def dropEvent(self,event): pass def mousePressEvent(self, event): if event.button()==Qt.MidButton or (event.button()==Qt.LeftButton and event.modifiers()&Qt.AltModifier): self.show_inspector(True) else: if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.mousePressEvent(event) self.updateGL() def mouseMoveEvent(self, event): if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.mouseMoveEvent(event) self.updateGL() def mouseReleaseEvent(self, event): if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.mouseReleaseEvent(event) self.updateGL() def wheelEvent(self, event): if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.wheelEvent(event) self.updateGL() def leaveEvent(self): pass def keyPressEvent(self,event): #if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.keyPressEvent(event) self.updateGL() def resize_event(self, width, height): self.rotor.resize_event(width,height) def draw_hud(self): width = self.gl_widget.width() height = self.gl_widget.height() glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0,width,0,height,-100,100) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glEnable(GL_LIGHTING) glEnable(GL_NORMALIZE) glMaterial(GL_FRONT,GL_AMBIENT,(0.2, 1.0, 0.2,1.0)) glMaterial(GL_FRONT,GL_DIFFUSE,(0.2, 1.0, 0.9,1.0)) glMaterial(GL_FRONT,GL_SPECULAR,(1.0 , 0.5, 0.2,1.0)) glMaterial(GL_FRONT,GL_SHININESS,20.0) enable_depth = glIsEnabled(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST) glColor(1.0,1.0,1.0) if self.font_render_mode == EMImageMXModule.FTGL: panels = len(self.rotor) idx = self.rotor.current_index() string = str(idx+1) + ' / ' + str(panels) bbox = self.font_renderer.bounding_box(string) x_offset = width-(bbox[3]-bbox[0]) - 10 y_offset = 10 glPushMatrix() glTranslate(x_offset,y_offset,0) glRotate(20,0,1,0) self.font_renderer.render_string(string) glPopMatrix() y_offset += bbox[4]-bbox[1] for s in self.hud_data: string = str(s) bbox = self.font_renderer.bounding_box(string) x_offset = width-(bbox[3]-bbox[0]) - 10 y_offset += 10 glPushMatrix() glTranslate(x_offset,y_offset,0) glRotate(20,0,1,0) self.font_renderer.render_string(string) glPopMatrix() y_offset += bbox[4]-bbox[1] else: pass if enable_depth: glEnable(GL_DEPTH_TEST) glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW)
class EMRotorModule(EMGUIModule): def get_gl_widget(self,qt_context_parent,gl_context_parent): if self.gl_widget == None: self.gl_context_parent = gl_context_parent self.qt_context_parent = qt_context_parent self.gl_widget = EM3DGLWindowOverride(self,self.rotor) return self.gl_widget def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin self.gl_context_parent = EMRotorWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setAcceptDrops(True) return self.qt_context_parent def __init__(self, data=None,application=None): EMGUIModule.__init__(self,ensure_gl_context=True) self.parent = None try: self.parent.setAcceptDrops(True) except: pass self.rotor = EMGLRotorWidget(self,0,-70,-15,EMGLRotorWidget.TOP_ROTARY,100) self.rotor.set_angle_range(40.0) self.rotor.set_mouse_mode("mxrotor") self.widget = EM3DGLWindowOverride(self,self.rotor) self.widget.set_draw_frame(False) self.z_near = 0 self.z_far = 0 self.inspector = None def __del__(self): for widget in self.rotor.get_widgets(): self.application.deregister_qt_emitter(widget.get_drawable().get_drawable()) def draw(self): lrt = self.widget.get_lr_bt_nf() z = self.gl_context_parent.get_depth_for_height(abs(lrt[3]-lrt[2])) z_near = z-lrt[4]-1000 z_trans = 0 z_far = z-lrt[5] if z_near < 0: z_trans = z_near z_near = 1 z_far -= z_trans if z_far < 0: z_far = 0.1 # hacking alert z_far += abs(lrt[3]-lrt[2]) # hacking alert if self.z_near != z_near or self.z_far != z_far: self.z_near = z_near self.z_far = z_far if isinstance(self.gl_context_parent,EMRotorWidget): self.gl_context_parent.set_near_far(self.z_near,self.z_far) else: print "bug 3" glPushMatrix() glTranslate(0,0,-z) self.widget.draw() glPopMatrix() def updateGL(self): try: self.gl_widget.updateGL() except: pass def mousePressEvent(self, event): if event.button()==Qt.MidButton: pass #self.show_inspector(True) else: self.widget.mousePressEvent(event) def mouseMoveEvent(self, event): self.widget.mouseMoveEvent(event) self.updateGL() def mouseReleaseEvent(self, event): self.widget.mouseReleaseEvent(event) self.updateGL() def wheelEvent(self, event): self.widget.wheelEvent(event) self.updateGL() def dragEnterEvent(self,event): pass def get_inspector(self): return None def dropEvent(self,event): pass def get_core_object(self): pass def add_file_dialog(self): fd = QtGui.QFileDialog(self.parent,"Open File",QtCore.QDir.currentPath(),QtCore.QString("Image files (*.img *.hed *.mrc)")) fd.show() fd.hide() self.add_qt_widget(fd) def keyPressEvent(self,event): if event.key() == Qt.Key_0: self.add_file_dialog() def add_qt_widget(self,qt_widget): from emfloatingwidgets import EMQtGLView, EM2DGLWindow gl_view = EMQtGLView(self,qt_widget) gl_view.setQtWidget(qt_widget) gl_widget = EM2DGLWindow(self,gl_view) #gl_widget = EMGLViewQtWidget(self.gl_context_parent) #gl_widget.setQtWidget(qt_widget) self.application.register_qt_emitter(gl_widget,self.application.get_qt_emitter(self)) self.rotor.add_widget(gl_widget) def width(self): return self.gl_widget.width() def height(self): return self.gl_widget.height() def register_animatable(self,animatable): self.qt_context_parent.register_animatable(animatable) def projection_or_viewport_changed(self): self.rotor.resize_event(-1,1) def update_rotor_position(self,*args): pass
class EMImageMXRotorModule(EMGUIModule): def get_desktop_hint(self): return "rotor" def get_gl_widget(self,qt_context_parent,gl_context_parent): from emfloatingwidgets import EM3DGLWindowOverride if self.gl_widget == None: self.gl_context_parent = gl_context_parent self.qt_context_parent = qt_context_parent self.gl_widget = EM3DGLWindowOverride(self,self.rotor) self.gl_widget.set_enable_clip(False) self.widget = self.gl_widget self.gl_widget.resize(640,640) self.disable_mx_zoom() self.disable_mx_translate() return self.gl_widget def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin self.gl_context_parent = EMImageMXRotorWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setAcceptDrops(True) return self.qt_context_parent def using_ftgl(self): return False def __init__(self, data=None,application=None): self.widget = None self.data=None self.rotor = EMGLRotorWidget(self,-15,70,-15,EMGLRotorWidget.BOTTOM_ROTARY,200) #self.rotor.set_angle_range(110.0) #self.rotor.set_child_mouse_events(False) self.rotor.set_mouse_mode("mxrotor") self.image_file_name = None # keeps track of the image file name (if any) - book keeping purposes only self.emdata_list_cache = None # all import emdata list cache, the object that stores emdata objects efficiently. Must be initialized via set_data or set_image_file_name self.default_mxs = 3 self.visible_mxs = self.default_mxs # the number of visible imagemxs in the rotor self.mx_rows = 4 # the number of rows in any given imagemx self.mx_cols = 4 # the number of columns in any given imagemx self.start_mx = 0 # the starting index for the currently visible set of imagemxs EMGUIModule.__init__(self,ensure_gl_context=True) self.inspector = None self.minden=0 self.maxden=1.0 self.mindeng=0 self.maxdeng=1.0 self.hist = None self.gamma=1.0 self.mmode = 'app' self.rot_mode = 'app' self.vals_to_display = ["Img #"] self.z_near = 0 self.z_far = 0 self.init_flag = True self.__init_font_renderer() if data: self.set_data(data) def __del__(self): for widget in self.rotor.get_widgets(): get_application().deregister_qt_emitter(widget.get_drawable().get_drawable()) def __init_gl_widget(self): self.widget = EM3DGLWindowOverride(self,self.rotor) self.widget.set_enable_clip(False) self.widget.set_draw_frame(False) self.disable_mx_zoom() self.disable_mx_translate() def __init_font_renderer(self): try: self.font_renderer = get_3d_font_renderer() self.font_renderer.set_face_size(32) self.font_renderer.set_depth(8) # self.font_renderer.set_font_mode(FTGLFontMode.EXTRUDE) self.font_render_mode = EMGUIModule.FTGL except: self.font_render_mode = EMGUIModule.GLUT def get_inspector(self): return self.inspector #def emit(self,*args,**kargs): #self.application.get_qt_emitter(self).emit(*args,**kargs) def set_selected(self,n,update_gl=True): widget = self.rotor[0] if widget != None: widget.get_drawable().get_drawable().set_selected(n,update_gl) def get_rows(self): return self.mx_rows def get_cols(self): return self.mx_cols def get_mxs(self): return self.visible_mxs def context(self): # asking for the OpenGL context from the parent return self.gl_context_parent.context() def is_visible(self,n): widget = self.rotor[0] if widget != None: img_offset = widget.get_drawable().get_drawable().get_img_num_offset() if n >= img_offset and n < (img_offset+self.mx_rows*self.mx_cols): return True else: return False else: return False def scroll_to(self,n,unused): widget = self.rotor[0] if widget != None: img_offset = widget.get_drawable().get_drawable().get_img_num_offset() scroll = (n-img_offset)/(self.mx_rows*self.mx_cols) self.rotor.explicit_animation(-scroll) def set_mx_cols(self,cols): self.mx_cols = cols self.emdata_list_cache.set_cache_size(8*self.visible_mxs*self.mx_rows*self.mx_cols) self.__refresh_rotor(True) self.updateGL() def set_mx_rows(self,rows): self.mx_rows = rows self.emdata_list_cache.set_cache_size(8*self.visible_mxs*self.mx_rows*self.mx_cols) self.__refresh_rotor(True) self.updateGL() def set_display_values(self,v2d): self.vals_to_display = v2d self.__refresh_rotor(False) self.updateGL() def set_mxs(self,mxs): self.visible_mxs = mxs self.emdata_list_cache.set_cache_size(8*self.visible_mxs*self.mx_rows*self.mx_cols) self.__regenerate_rotor() # this could be done more efficiently self.__refresh_rotor_size() self.updateGL() def set_mouse_mode(self,mode): self.mmode = mode try: for i in range(self.visible_mxs): w = self.rotor[i].get_drawable() w.set_mouse_mode(self.mmode) except: pass def set_scale(self,scale): pass def get_density_min(self): return self.rotor[0].get_drawable().get_drawable().get_density_min() def get_density_max(self): return self.rotor[0].get_drawable().get_drawable().get_density_max() def get_hist(self): return self.rotor[0].get_drawable().get_drawable().get_hist() def set_density_max(self,val): self.maxden=val self.update_min_max_gamma() def set_density_min(self,val): self.minden=val self.update_min_max_gamma() def set_gamma(self,val): self.gamma=val self.update_min_max_gamma() def set_plane(self,plane): self.plane = plane def disable_mx_zoom(self): ''' Disable mx zoom. ''' self.rotor.target_zoom_events_allowed(False) def disable_mx_translate(self): self.widget.target_translations_allowed(False) def allow_camera_rotations(self,bool=False): self.widget.allow_camera_rotations(bool) def pop_box_image(self,idx): val = self.emdata_list_cache.delete_box(idx) if val == 1: self.max_idx = self.emdata_list_cache.get_max_idx() self.__refresh_rotor() elif val == 2: w = self.rotor[0].get_drawable() w.force_display_update() else: print 'failed to delete box image' def update_min_max_gamma(self,update_gl=True): for i in range(self.visible_mxs): w = self.rotor[i].get_drawable().get_drawable() w.set_min_max_gamma(self.minden,self.maxden,self.gamma,False) if i == 0 and self.inspector != None: try: self.inspector.set_hist(w.get_hist(),self.minden,self.maxden) except: # the histogram isn't created yet - this is a FIXME pass if update_gl: self.updateGL() def set_den_range(self,minden,maxden): self.minden=minden self.maxden=maxden self.update_min_max_gamma() def update_rotor_position(self,inc): self.start_mx += inc if inc > 0: end_changed = self.visible_mxs start_changed = self.visible_mxs-inc #print start_changed,end_changed #for idx in range(start_changed,end_changed): elif inc < 0: end_changed = -inc start_changed = 0 else: return #print "iterating through",start_changed,end_changed,"start_mx is",self.start_mx self.__update_rotor_range(start_changed ,end_changed) try: w = self.rotor[0].get_drawable().get_drawable() self.inspector.set_hist(w.get_hist(),self.minden,self.maxden) except: pass def __update_rotor_range(self,start_changed,end_changed): num_per_view = self.mx_rows*self.mx_cols for idx in range(start_changed,end_changed): n = idx+ self.start_mx panel = n if panel != 0: panel %= self.get_num_panels() start_idx = panel*num_per_view image_offset = start_idx if image_offset != 0: image_offset %= self.emdata_list_cache.get_max_idx() d = [] if image_offset > (self.emdata_list_cache.get_max_idx()-num_per_view): num_visible = self.emdata_list_cache.get_max_idx() - image_offset num_none = num_per_view - num_visible for i in range(start_idx,start_idx+num_visible): d.append(self.emdata_list_cache[i]) for i in range(num_none): d.append(None) else: for i in range(start_idx,start_idx+num_per_view): d.append(self.emdata_list_cache[i]) w = self.rotor[idx].get_drawable().get_drawable() w.set_data(d,"",False) w.set_img_num_offset(image_offset) w.set_max_idx(self.emdata_list_cache.get_max_idx()) w.set_min_max_gamma(self.minden,self.maxden,self.gamma,False) def get_num_panels(self): return int(ceil(float(self.emdata_list_cache.get_max_idx())/ (self.mx_rows*self.mx_cols))) def set_rotor_mode(self,mode): self.rot_mode = mode self.rotor.set_mouse_mode(mode) def optimize_fit(self,update_gl=True): render_width = self.gl_widget.width() render_height = self.gl_widget.height() try: self.mx_rows = render_width/self.emdata_list_cache.get_xsize() self.mx_cols = render_height/self.emdata_list_cache.get_ysize() if self.mx_rows == 0: self.mx_rows = 1 if self.mx_cols == 0: self.mx_cols = 1 except: return try: self.inspector.set_n_cols(self.mx_cols) self.inspector.set_n_rows(self.mx_rows) except: pass #try: #self.widget.set_width(render_width) #self.widget.set_height(render_height) #except: pass self.__refresh_rotor(True) if update_gl: self.updateGL() def set_frozen(self,frozen): self.rotor.set_frozen(frozen) def set_shapes(self,shapes,shrink): self.rotor.set_shapes(shapes,shrink) def register_animatable(self,animatable): self.qt_context_parent.register_animatable(animatable) def width(self): try: return self.gl_widget.width() except: return 0 def height(self): try: return self.gl_widget.height() except: return 0 def get_image_file_name(self): ''' warning - could return none in some circumstances''' try: return self.gl_parent.get_image_file_name() except: return None def get_image(self,idx): return self.emdata_list_cache[idx] def set_data(self,data): if data == None or not isinstance(data,list) or len(data)==0: self.data = [] return fac = int(ceil(float(len(data))/(self.mx_rows*self.mx_cols))) if fac == 0: fac = 1 self.emdata_list_cache = EMDataListCache(data,8*self.visible_mxs*self.mx_rows*self.mx_cols) if self.init_flag: if fac < self.visible_mxs: self.visible_mxs = fac self.__regenerate_rotor() self.init_flag = False else: # print "here we are", fac,self.visible_mxs,self.default_mxs if fac < self.visible_mxs: self.visible_mxs = fac self.__regenerate_rotor() self.__refresh_rotor_size() elif self.visible_mxs < self.default_mxs and fac >= self.default_mxs: # print "setting visible mxs" self.visible_mxs = self.default_mxs self.__regenerate_rotor() self.__refresh_rotor_size() elif fac > self.visible_mxs and self.visible_mxs < self.default_mxs: self.visible_mxs = fac self.__regenerate_rotor() self.__refresh_rotor_size() else: self.__refresh_rotor(True) def set_image_file_name(self,name): #print "set image file name",name self.image_file_name = name self.emdata_list_cache = EMDataListCache(name) self.__regenerate_rotor() def __refresh_rotor(self,inc_size=False): self.__update_rotor_range(0,self.visible_mxs) if inc_size: self.__refresh_rotor_size() def __refresh_rotor_size(self): if len(self.rotor) == 0: return self.render_width = self.gl_widget.width() self.render_height = self.gl_widget.height() width = self.mx_rows*(self.emdata_list_cache.get_xsize()+2)-2 height = self.mx_cols*(self.emdata_list_cache.get_ysize()+2)-2 scale1 = self.render_height/float(height) scale2 = self.render_width/float(width) if self.render_width > self.render_height: self.render_height = float(height)/width*self.render_width scale = scale2 else: self.render_width = float(width)/height*self.render_height scale = scale1 for idx in range(0,self.visible_mxs): e = self.rotor[idx] w = e.get_drawable().get_drawable() w.set_scale(scale,False) e.set_width(self.render_width) e.set_height(self.render_height) e.set_update_frame(True) ##w.set_mx_cols(self.mx_rows,False) self.rotor.update() def __regenerate_rotor(self): for widget in self.rotor.get_widgets(): get_application().deregister_qt_emitter(widget.get_drawable().get_drawable()) self.rotor.clear_widgets() # self.parent.updateGL() # i can't figure out why I have to do this (when this function is called from set_mxs num_per_view = self.mx_rows*self.mx_cols for idx in range(self.start_mx,self.start_mx+self.visible_mxs): n = idx panel = n if panel != 0: panel %= self.get_num_panels() start_idx = panel*num_per_view image_offset = start_idx if image_offset != 0: image_offset %= self.emdata_list_cache.get_max_idx() #print idx,panel,image_offset d = [] if image_offset > (self.emdata_list_cache.get_max_idx()-num_per_view): num_visible = self.emdata_list_cache.get_max_idx() - image_offset num_none = num_per_view - num_visible #print num_visible,num_none for i in range(start_idx,start_idx+num_visible): d.append(self.emdata_list_cache[i]) for i in range(num_none): d.append(None) else: for i in range(start_idx,start_idx+num_per_view): d.append(self.emdata_list_cache[i]) e = EM2DGLView(self,d) e.get_drawable().set_app(get_application()) get_application().register_qt_emitter(e.get_drawable(),get_application().get_qt_emitter(self)) x = EM2DGLWindow(self,e) x.decoration.draw_x_enabled = False x.decoration.color_flag = "black" self.rotor.add_widget(x) w = e.get_drawable() w.set_use_display_list(True) # saves HEAPS of time, makes interaction much smoother w.set_reroute_delete_target(self) w.set_draw_background(True) w.set_mouse_mode(self.mmode) w.set_display_values(self.vals_to_display,False) w.set_img_num_offset(image_offset) w.set_max_idx(self.emdata_list_cache.get_max_idx()) e = self.rotor[0] w = e.get_drawable().get_drawable() self.minden = w.get_density_min() self.maxden = w.get_density_max() self.hist = w.get_hist() self.mindeng = self.minden self.maxdeng = self.maxden self.gamma = w.get_gamma() self.update_min_max_gamma(False) self.__refresh_rotor_size() def updateGL(self): try: self.gl_widget.updateGL() except: pass def render(self): if self.widget == None: self.__init_gl_widget() if not self.get_qt_context_parent().isVisible(): return if self.emdata_list_cache == None: return lrt = self.widget.get_lr_bt_nf() GL.glEnable(GL.GL_DEPTH_TEST) GL.glEnable(GL.GL_LIGHTING) z = self.gl_context_parent.get_depth_for_height(abs(lrt[3]-lrt[2])) z2 = self.gl_context_parent.get_depth_for_width(abs(lrt[1]-lrt[0])) if z2 > z: z = z2 z_near = z-lrt[4]-100 z_trans = 0 z_far = z-lrt[5] if z_near < 0: z_trans = z_near z_near = 1 z_far -= z_trans if z_far < 0: z_far = 0.1 # hacking alert z_far += abs(lrt[3]-lrt[2]) # hacking alert if self.z_near != z_near or self.z_far != z_far: self.z_near = z_near self.z_far = z_far if isinstance(self.gl_context_parent,EMImageMXRotorWidget): self.gl_context_parent.set_near_far(self.z_near,self.z_far) else: print "bug 2" GL.glPushMatrix() glTranslate(-(lrt[1]+lrt[0])/2.0,-(lrt[3]+lrt[2])/2.0,-z) self.widget.draw() GL.glPopMatrix() self.draw_hud() def dragEnterEvent(self,event): pass def dropEvent(self,event): pass def get_inspector(self): if not self.inspector: self.inspector=EMImageInspectorMX(self,allow_col_variation=True,allow_window_variation=True,allow_opt_button=True) self.inspector.set_limits(self.mindeng,self.maxdeng,self.minden,self.maxden) return self.inspector def mousePressEvent(self, event): if event.button()==Qt.MidButton or (event.button()==Qt.LeftButton and event.modifiers()&Qt.AltModifier): self.show_inspector(True) else: self.widget.mousePressEvent(event) self.updateGL() def mouseMoveEvent(self, event): if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.mouseMoveEvent(event) self.updateGL() def mouseReleaseEvent(self, event): self.widget.mouseReleaseEvent(event) self.updateGL() def wheelEvent(self, event): if self.widget.isinwin(event.x(),self.gl_context_parent.viewport_height()-event.y()): self.widget.wheelEvent(event) self.updateGL() def leaveEvent(self,event): pass def keyPressEvent(self,event): self.widget.keyPressEvent(event) self.updateGL() def resize_event(self, width, height): if self.widget != None: self.widget.update() self.rotor.resize_event(width,height) self.optimize_fit(False) def projection_or_viewport_changed(self): self.rotor.resize_event(-1,1) def save_lst(self): self.emdata_list_cache.save_lst() def save_data(self): self.emdata_list_cache.save_data() def get_frame_buffer(self): return self.gl_widget.get_frame_buffer() ligh_yellow_diffuse = (.84,.82,.38,1.0) ligh_yellow_ambient = (.83,.83,.38,1.0) ligh_yellow_specular = (.76,.75,.39,1.0) def draw_hud(self): width = self.gl_widget.viewport_width() height =self.gl_widget.viewport_height() glMatrixMode(GL_PROJECTION) glPushMatrix() glLoadIdentity() glOrtho(0,width,0,height,-200,200) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glDisable(GL_LIGHTING) glEnable(GL_NORMALIZE) glMaterial(GL_FRONT,GL_AMBIENT,EMImageMXRotorModule.ligh_yellow_ambient) glMaterial(GL_FRONT,GL_DIFFUSE,EMImageMXRotorModule.ligh_yellow_diffuse) glMaterial(GL_FRONT,GL_SPECULAR,EMImageMXRotorModule.ligh_yellow_specular) glMaterial(GL_FRONT,GL_SHININESS,30.0) enable_depth = glIsEnabled(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST) glEnable(GL_TEXTURE_2D) glColor(1.0,1.0,1.0) glColor(*EMImageMXRotorModule.ligh_yellow_specular) if self.font_render_mode == EMImageMXModule.FTGL: panels = self.get_num_panels() idx = self.start_mx if idx != 0: idx %= panels string = str(idx+1) + ' / ' + str(panels) glPushMatrix() glTranslate(10,height-1.2*self.font_renderer.get_face_size(),0) glRotate(20,0,1,0) self.font_renderer.render_string(string) glPopMatrix() else: pass if enable_depth: glEnable(GL_DEPTH_TEST) glMatrixMode(GL_PROJECTION) glPopMatrix() glMatrixMode(GL_MODELVIEW)
class EM3DModule(EMImage3DGUIModule): def get_qt_widget(self): if self.qt_context_parent == None: from emimageutil import EMParentWin from emimage3d import EMImage3DWidget self.under_qt_control = True self.gl_context_parent = EMImage3DWidget(self) self.qt_context_parent = EMParentWin(self.gl_context_parent) self.gl_widget = self.gl_context_parent self.qt_context_parent.setWindowIcon(QtGui.QIcon(get_image_directory() +"single_image_3d.png")) return self.qt_context_parent def get_gl_widget(self,qt_context_parent,gl_context_parent): self.under_qt_control = False ret = EMImage3DGUIModule.get_gl_widget(self,qt_context_parent,gl_context_parent) self.gl_widget.setWindowTitle(remove_directories_from_name(self.file_name)) self.__set_module_contexts() return ret def get_desktop_hint(self): return "image" def __init__(self,application=None,ensure_gl_context=True,application_control=True): EMImage3DGUIModule.__init__(self,application,ensure_gl_context=ensure_gl_context,application_control=application_control) #EMLightsDrawer.__init__(self) self.cam = Camera2(self) self.vdtools = EMViewportDepthTools(self) self.perspective = False self.colors = get_default_gl_colors() self.perspective = True # basic shapes will be stored in these lists self.gq = None # will be a glu quadric self.cylinderdl = 0 # will be a cylinder with no caps self.diskdl = 0 # this will be a flat disk self.spheredl = 0 # this will be a low resolution sphere self.highresspheredl = 0 # high resolution sphere self.cappedcylinderdl = 0 # a capped cylinder self.first_render_flag = True # this is used to catch the first call to the render function - so you can do an GL context sensitive initialization when you know there is a valid context self.inspector = None # will be the inspector, i.e. an instance of an EM3DInspector self.radius = 100 self.font_renderer = None # will be a 3D fonts renderer def __del__(self): if self.under_qt_control and not self.dont_delete_parent: self.qt_context_parent.deleteLater() self.core_object.deleteLater() def width(self): try: return self.gl_widget.width() except: return 0 def height(self): try: return self.gl_widget.height() except: return 0 def initializeGL(self): # put your own initialization things in here glEnable(GL_LIGHTING) glEnable(GL_NORMALIZE) def load_gl_color(self,name): color = self.colors[name] glColor(color["ambient"]) glMaterial(GL_FRONT,GL_AMBIENT,color["ambient"]) glMaterial(GL_FRONT,GL_DIFFUSE,color["diffuse"]) glMaterial(GL_FRONT,GL_SPECULAR,color["specular"]) glMaterial(GL_FRONT,GL_EMISSION,color["emission"]) glMaterial(GL_FRONT,GL_SHININESS,color["shininess"]) def render(self): if self.first_render_flag: # self.initializeGL() # self.init_basic_shapes() # only does something the first time you call it # self.init_font_renderer() if not self.perspective:self.gl_context_parent.load_orthographic() else: self.gl_context_parent.load_perspective() self.first_render_flag = False #self.vdtools.set_update_P_inv() glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1,1) glPopMatrix() glPushMatrix() self.cam.position() self.draw_objects() glPopMatrix() # glPushMatrix() # self.cam.translate_only() # EMLightsDrawer.draw(self) # glPopMatrix() def draw_objects(self): # glPushMatrix() # glScale(50,50,50) # self.load_gl_color("red") # glCallList(self.highresspheredl) # glPopMatrix() glPushMatrix() glTranslate(100,0,0) glScale(50,50,50) self.load_gl_color("blue") glCallList(self.spheredl) glPopMatrix() glPushMatrix() glTranslate(0,100,0) glScale(50,10,10) glTranslate(-0.5,0,0) glRotate(90,0,1,0) self.load_gl_color("emerald") glCallList(self.cylinderdl) glPopMatrix() glPushMatrix() glTranslate(-100,25,0) glScale(10,50,10) glTranslate(-0.5,0,0) glRotate(90,1,0,0) self.load_gl_color("gold") glCallList(self.cappedcylinderdl) glPopMatrix() glPushMatrix() glTranslate(0,-100,0) glScale(15,15,15) self.load_gl_color("copper") glCallList(self.diskdl) glPopMatrix() glPushMatrix() glTranslate(0,-100,-10) glScale(15,15,15) glRotate(180,0,1,0) self.load_gl_color("silver") glCallList(self.diskdl) glPopMatrix() glPushMatrix() glTranslate(0,0,50) s = "bdb:EMAN2" bbox = self.font_renderer.bounding_box(s) glTranslate(-(bbox[3]-bbox[0])/2, -(bbox[4]-bbox[1])/2,-(bbox[5]-bbox[02])/2) self.font_renderer.render_string(s) glPopMatrix() glPushMatrix() glTranslate(0,-50,-50) s = "=^_^=" bbox = self.font_renderer.bounding_box(s) glTranslate(-(bbox[3]-bbox[0])/2, -(bbox[4]-bbox[1])/2,-(bbox[5]-bbox[02])/2) self.font_renderer.render_string(s) glPopMatrix() def init_font_renderer(self): if self.font_renderer == None: self.font_renderer = get_3d_font_renderer() self.font_renderer.set_face_size(20) self.font_renderer.set_depth(12) self.font_renderer.set_font_mode(FTGLFontMode.EXTRUDE) def init_basic_shapes(self): #self.gl_context_parent.makeCurrent() if self.gq == None: self.gq=gluNewQuadric() # a quadric for general use gluQuadricDrawStyle(self.gq,GLU_FILL) gluQuadricNormals(self.gq,GLU_SMOOTH) gluQuadricOrientation(self.gq,GLU_OUTSIDE) gluQuadricTexture(self.gq,GL_FALSE) if ( self.cylinderdl == 0 ): self.cylinderdl=glGenLists(1) glNewList(self.cylinderdl,GL_COMPILE) glPushMatrix() gluCylinder(self.gq,1.0,1.0,1.0,12,2) glPopMatrix() glEndList() if self.diskdl == 0: self.diskdl=glGenLists(1) glNewList(self.diskdl,GL_COMPILE) gluDisk(self.gq,0,1,12,2) glEndList() if self.spheredl == 0: self.spheredl=glGenLists(1) glNewList(self.spheredl,GL_COMPILE) gluSphere(self.gq,.5,4,2) glEndList() if self.highresspheredl == 0: self.highresspheredl=glGenLists(1) glNewList(self.highresspheredl,GL_COMPILE) gluSphere(self.gq,.5,16,16) glEndList() if ( self.cappedcylinderdl == 0 ): self.cappedcylinderdl=glGenLists(1) glNewList(self.cappedcylinderdl,GL_COMPILE) glCallList(self.cylinderdl) glPushMatrix() glTranslate(0,0,1) glCallList(self.diskdl) glPopMatrix() glPushMatrix() glRotate(180,0,1,0) glCallList(self.diskdl) glPopMatrix() glEndList() def eye_coords_dif(self,x1,y1,x2,y2,mdepth=True): return self.vdtools.eye_coords_dif(x1,y1,x2,y2,mdepth) def resizeEvent(self, width, height): for i in self.viewables: i.resizeEvent() def get_inspector(self): if self.inspector == None: self.inspector = EM3DInspector(self) return self.inspector def set_cam_z(self,z): self.cam.set_cam_z( z ) self.updateGL() def set_cam_y(self,y): self.cam.set_cam_y( y ) self.updateGL() def set_cam_x(self,x): self.cam.set_cam_x( x ) self.updateGL() def set_scale(self,val): self.cam.scale = val self.updateGL() def resizeEvent(self,width=0,height=0): self.vdtools.set_update_P_inv() def load_rotation(self,t3d): self.cam.load_rotation(t3d) self.updateGL() def get_start_z(self): return self.gl_context_parent.get_start_z() def get_near_plane_dims(self): return self.gl_context_parent.get_near_plane_dims() def set_perspective(self,bool): self.perspective = bool glMatrixMode(GL_PROJECTION) glLoadIdentity() if not self.perspective:self.gl_context_parent.load_orthographic() else: self.gl_context_parent.load_perspective() glMatrixMode(GL_MODELVIEW) self.updateGL()