class EMIsosurfaceModel(EM3DModel): def eye_coords_dif(self, x1, y1, x2, y2, mdepth=True): return self.vdtools.eye_coords_dif(x1, y1, x2, y2, mdepth) def __init__(self, gl_widget, image=None, enable_file_browse=False): self.data = None EM3DModel.__init__(self, gl_widget) self.init() self.initialized = True self.cam = Camera2(self) self.tex_name = 0 self.texture = False self.brightness = 0 self.contrast = 10 self.glcontrast = 1.0 self.glbrightness = 0.0 self.rank = 1 self.inspector = None self.data_copy = None self.vdtools = EMViewportDepthTools(self) self.enable_file_browse = enable_file_browse self.force_update = False if image: self.set_data(image) # def __del__(self): # print "iso died" # pass def set_force_update(self, val=True): self.force_update = val def get_type(self): return "Isosurface" def get_emit_signals_and_connections(self): return {"set_threshold": self.set_threshold} def update_data_and_texture(self): self.data_copy = self.data.copy() self.data_copy.add(self.brightness) self.data_copy.mult(self.contrast) hist = self.data_copy.calc_hist(256, self.minden, self.maxden) self.inspector.set_hist(hist, self.minden, self.maxden) if (self.texture): self.gen_texture() def gen_texture(self): if (self.texture == False): return if (self.tex_name != 0): glDeleteTextures(self.tex_name) if (self.data_copy == None): self.tex_name = GLUtil.gen_gl_texture(self.data) else: self.tex_name = GLUtil.gen_gl_texture(self.data_copy) def render(self): if (not isinstance(self.data, EMData)): return #a = time() lighting = glIsEnabled(GL_LIGHTING) cull = glIsEnabled(GL_CULL_FACE) depth = glIsEnabled(GL_DEPTH_TEST) polygonmode = glGetIntegerv(GL_POLYGON_MODE) normalize = glIsEnabled(GL_NORMALIZE) glEnable(GL_CULL_FACE) glCullFace(GL_BACK) #glDisable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) glEnable(GL_NORMALIZE) #glDisable(GL_NORMALIZE) if (self.wire): glPolygonMode(GL_FRONT, GL_LINE) else: glPolygonMode(GL_FRONT, GL_FILL) if self.light: glEnable(GL_LIGHTING) else: glDisable(GL_LIGHTING) glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1, 1) glPopMatrix() self.cam.position() glShadeModel(GL_SMOOTH) if (self.isodl == 0 or self.force_update): self.get_iso_dl() self.force_update = False glStencilFunc(GL_EQUAL, self.rank, 0) glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) glMaterial(GL_FRONT, GL_AMBIENT, self.colors[self.isocolor]["ambient"]) glMaterial(GL_FRONT, GL_DIFFUSE, self.colors[self.isocolor]["diffuse"]) glMaterial(GL_FRONT, GL_SPECULAR, self.colors[self.isocolor]["specular"]) glMaterial(GL_FRONT, GL_SHININESS, self.colors[self.isocolor]["shininess"]) glMaterial(GL_FRONT, GL_EMISSION, self.colors[self.isocolor]["emission"]) glColor(self.colors[self.isocolor]["ambient"]) glPushMatrix() glTranslate(-self.data.get_xsize() / 2.0, -self.data.get_ysize() / 2.0, -self.data.get_zsize() / 2.0) if (self.texture): glScalef(self.data.get_xsize(), self.data.get_ysize(), self.data.get_zsize()) glCallList(self.isodl) glPopMatrix() self.draw_bc_screen() glStencilFunc(GL_ALWAYS, 1, 1) if self.cube: glDisable(GL_LIGHTING) glPushMatrix() self.draw_volume_bounds() glPopMatrix() if (lighting): glEnable(GL_LIGHTING) else: glDisable(GL_LIGHTING) if (not cull): glDisable(GL_CULL_FACE) else: glDisable(GL_CULL_FACE) if (depth): glEnable(GL_DEPTH_TEST) else: glDisable(GL_DEPTH_TEST) if (not normalize): glDisable(GL_NORMALIZE) if (polygonmode[0] == GL_LINE): glPolygonMode(GL_FRONT, GL_LINE) else: glPolygonMode(GL_FRONT, GL_FILL) #if ( polygonmode[1] == GL_LINE ): glPolygonMode(GL_BACK, GL_LINE) #else: glPolygonMode(GL_BACK, GL_FILL) #print "total time is", time()-a def init(self): self.mmode = 0 self.inspector = None self.isothr = 0.5 self.isorender = None self.isodl = 0 self.smpval = -1 self.griddl = 0 self.scale = 1.0 self.cube = False self.wire = False self.light = True def get_iso_dl(self): # create the isosurface display list self.isorender.set_surface_value(self.isothr) self.isorender.set_sampling(self.smpval) if (self.texture): if (self.tex_name == 0): self.update_data_and_texture() face_z = False if self.data.get_zsize() <= 2: face_z = True if (self.texture): self.isodl = GLUtil.get_isosurface_dl(self.isorender, self.tex_name, face_z) else: self.isodl = GLUtil.get_isosurface_dl(self.isorender, 0, face_z) #time2 = clock() #dt1 = time2 - time1 #print "It took %f to render the isosurface" %dt1 def update_data(self, data): if data == None or (isinstance(data, EMData) and data.get_zsize() <= 1): print "Error, tried to set data that is invalid for EMIsosurface" return self.data = data self.isorender = MarchingCubes(data) self.get_iso_dl() self.updateGL() def set_data(self, data): """Pass in a 3D EMData object""" if data == None: print "Error, tried to set data that is invalid for EMIsosurface" return self.data = data if self.isodl != 0: self.force_update = True self.minden = data.get_attr("minimum") self.maxden = data.get_attr("maximum") mean = data.get_attr("mean") sigma = data.get_attr("sigma") #d = data.get_attr_dict() #x,y,z,act = 0,0,0,False #if d.has_key("origin_x"): #x = d["origin_x"]/d["apix_x"] + data.get_xsize()/2 #act = True #if d.has_key("origin_y"): #y = d["origin_y"]/d["apix_y"] + data.get_ysize()/2 #act = True #if d.has_key("origin_z"): #z = d["origin_z"]/d["apix_z"] + data.get_zsize()/2 #act = True if not self.inspector or self.inspector == None: self.inspector = EMIsoInspector(self) #if act: #self.inspector.set_xyz_trans(x,y,z) hist = data.calc_hist(256, self.minden, self.maxden) self.inspector.set_hist(hist, self.minden, self.maxden) iso_threshold = mean + 3.0 * sigma self.inspector.set_thresholds(self.minden, self.maxden, iso_threshold) self.isothr = iso_threshold self.brightness = -self.isothr self.isorender = MarchingCubes(data) self.inspector.set_sampling_range(self.isorender.get_sampling_range()) # nx,ny,nz = data.get_xsize(),data.get_ysize(),data.get_zsize() # if nx > 256 or ny > 256 or nz > 256: # self.isorender.set_sampling(2) self.load_colors() self.inspector.set_materials(self.colors, self.isocolor) from emglobjects import EM3DGLWidget if isinstance(self.get_gl_widget(), EM3DGLWidget): self.get_gl_widget().set_camera_defaults(self.data) def load_colors(self): self.colors = get_default_gl_colors() self.isocolor = "bluewhite" def get_material(self): return self.colors[self.isocolor] def set_threshold(self, val): if (self.isothr != val): self.isothr = val self.brightness = -val if (self.texture): self.update_data_and_texture() self.get_iso_dl() if self.emit_events: self.emit(QtCore.SIGNAL("set_threshold"), val) self.updateGL() def set_sample(self, val): if (self.smpval != int(val)): # the minus two is here because the marching cubes thinks -1 is the high level of detail, 0 is the next best and so forth # However the user wants the highest level of detail to be 1, and the next best to be 2 and then 3 etc self.smpval = int(val) - 2 self.get_iso_dl() self.updateGL() def set_material(self, val): #print val self.isocolor = str(val) self.updateGL() def toggle_cube(self): self.cube = not self.cube self.updateGL() def toggle_wire(self, val): self.wire = not self.wire self.updateGL() def toggle_light(self, val): self.light = not self.light self.updateGL() def toggle_texture(self): self.texture = not self.texture if (self.texture): self.update_data_and_texture() self.get_iso_dl() self.updateGL() def update_inspector(self, t3d): self.get_inspector().update_rotations(t3d) def get_inspector(self): if not self.inspector: self.inspector = EMIsoInspector(self, self.enable_file_browse) return self.inspector def set_contrast(self, val): self.contrast = val self.update_data_and_texture() self.updateGL() def set_brightness(self, val): self.brightness = val self.update_data_and_texture() self.updateGL() def resize(self): self.vdtools.set_update_P_inv() def get_mrc_file(self): #added by muthu return self.get_inspector().mrcfileName
class EM3DSliceModel(EM3DModel): def __init__(self, gl_widget, image=None): self.data = None EM3DModel.__init__(self, gl_widget) self.init() self.initialized = True self.inspector=None self.axes = [] self.axes.append( Vec3f(1,0,0) ) self.axes.append( Vec3f(0,1,0) ) self.axes.append( Vec3f(0,0,1) ) self.axes_idx = 2 self.track = False self.bright = 0 self.contrast = 1.0 self.busy = True if image : self.set_data(image) def set_contrast(self,val): self.contrast = val self.generate_current_display_list() self.updateGL() def set_brightness(self,val): self.bright = val self.generate_current_display_list() self.updateGL() # def __del__(self): # print "slice died" def get_type(self): return "Slice Viewer" def init(self): self.data=None self.mmode=0 self.cam = Camera2(self) self.vdtools = EMViewportDepthTools(self) self.cube = False self.inspector=None self.tex_name = 0 self.tex_dl = 0 self.glcontrast = 1.0 self.glbrightness = 0.0 self.rank = 1 self.glflags = EMOpenGLFlagsAndTools() # OpenGL flags - this is a singleton convenience class for testing texture support def eye_coords_dif(self,x1,y1,x2,y2,mdepth=True): return self.vdtools.eye_coords_dif(x1,y1,x2,y2,mdepth) def update_data(self,data): if data==None: print "Error, the data is empty" return if (isinstance(data,EMData) and data.get_zsize()<=1) : print "Error, the data is not 3D" return # self.data = data.copy() # # min = self.data.get_attr("minimum") # max = self.data.get_attr("maximum") # # self.data.add(-min) # self.data.mult(1/(max-min)) self.generate_current_display_list() self.updateGL() def set_default_contrast_settings(self): min = self.data.get_attr("minimum") max = self.data.get_attr("maximum") # # self.data.add(-min) # self.data.mult(1/(max-min)) self.bright = -min if max != min: self.contrast = 1.0/(max-min) else: self.contrast = 1 def set_data(self,data,fact=1.0): """Pass in a 3D EMData object""" self.busy = True if data==None: print "Error, the data is empty" return if (isinstance(data,EMData) and data.get_zsize()<=1) : print "Error, the data is not 3D" self.busy = False return self.data = data self.set_default_contrast_settings() if not self.inspector or self.inspector ==None: self.inspector=EM3DSliceInspector(self) self.inspector.set_contrast_bright(self.contrast,self.bright) hist = self.data.calc_hist(256,0,1.0,self.bright,self.contrast) self.inspector.set_hist(hist,0,1.0) self.slice = data.get_zsize()/2 self.zslice = data.get_zsize()/2-1 if self.zslice < 0: self.zslice = 0 self.yslice = data.get_ysize()/2-1 if self.yslice < 0: self.yslice = 0 self.xslice = data.get_xsize()/2-1 if self.xslice < 0: self.xslice = 0 self.trackslice = self.xslice self.axis = 'z' self.inspector.set_sliceRange(0,data.get_zsize()-1) self.inspector.set_slice(self.zslice) self.generate_current_display_list() from emglobjects import EM3DGLWidget if isinstance(self.get_gl_widget(),EM3DGLWidget): self.get_gl_widget().set_camera_defaults(self.data) if ( self.tex_dl != 0 ): glDeleteLists( self.tex_dl, 1) self.tex_dl = 0 self.busy = False def get_eman_transform(self,p): if ( p[2] == 0 ): alt = 90 else : alt = acos(p[2])*180.0/pi phi = atan2(p[0],p[1]) phi *= 180.0/pi return [Transform({"type":"eman","alt":alt,"phi":phi}),alt,phi] def get_dimension_size(self): if ( self.axes_idx == 0 ): return self.data.get_xsize() elif ( self.axes_idx == 1 ): return self.data.get_ysize() elif ( self.axes_idx == 2 ): return self.data.get_zsize() else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return self.data.get_xsize() #return 0 def get_correct_dims_2d_emdata(self): if ( self.axes_idx == 0 ): return EMData(self.data.get_ysize(),self.data.get_zsize()) elif ( self.axes_idx == 1 ): return EMData(self.data.get_xsize(),self.data.get_zsize()) elif ( self.axes_idx == 2 ): return EMData(self.data.get_xsize(),self.data.get_ysize()) else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return EMData(self.data.get_xsize(),self.data.get_zsize()) def generate_current_display_list(self): if self.busy: return if ( self.tex_dl != 0 ): glDeleteLists( self.tex_dl, 1) self.tex_dl = glGenLists(1) if (self.tex_dl == 0): return #OpenGL is initialized yet self.gen_2D_texture() def gen_2D_texture(self): glNewList(self.tex_dl,GL_COMPILE) n = self.get_dimension_size() v = self.axes[self.axes_idx] [t,alt,phi] = self.get_eman_transform(v) nn = float(self.slice)/float(n) trans = (nn-0.5)*v t.set_trans(n*trans) if False and EMUtil.cuda_available(): # disable for the time being - big textures won't work on CPU tmp = self.data.cut_slice_cuda(t) else: tmp = self.get_correct_dims_2d_emdata() tmp.cut_slice(self.data,t,True) tmp.add(self.bright) tmp.mult(self.contrast) hist = tmp.calc_hist(256,0,1.0,self.bright,self.contrast) self.inspector.set_hist(hist,0,1.0) if ( self.tex_name != 0 ): glDeleteTextures(self.tex_name) self.tex_name = 0 self.tex_name = self.glflags.gen_textureName(tmp) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, self.tex_name) #glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # if ( not data_dims_power_of(self.data,2) and self.glflags.npt_textures_unsupported()): # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # else: # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glPushMatrix() glTranslate(trans[0]+0.5,trans[1]+0.5,trans[2]+0.5) glRotatef(-phi,0,0,1) glRotatef(-alt,1,0,0) glBegin(GL_QUADS) glTexCoord2f(0,0) glVertex2f(-0.5,-0.5) glTexCoord2f(1,0) glVertex2f( 0.5,-0.5) glTexCoord2f(1,1) glVertex2f( 0.5, 0.5) glTexCoord2f(0,1) glVertex2f(-0.5, 0.5) glEnd() glPopMatrix() glDisable(GL_TEXTURE_2D) glEndList() def render(self): if self.busy: return lighting = glIsEnabled(GL_LIGHTING) cull = glIsEnabled(GL_CULL_FACE) polygonmode = glGetIntegerv(GL_POLYGON_MODE) glDisable(GL_LIGHTING) glDisable(GL_CULL_FACE) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1,1) glPopMatrix() self.cam.position() self.vdtools.store_model() if ( self.track ): self.loadTrackAxis() self.generate_current_display_list() if ( self.tex_dl == 0 ): self.generate_current_display_list() glStencilFunc(GL_EQUAL,self.rank,0) glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE) glPushMatrix() glTranslate(-self.data.get_xsize()/2.0,-self.data.get_ysize()/2.0,-self.data.get_zsize()/2.0) glScalef(self.data.get_xsize(),self.data.get_ysize(),self.data.get_zsize()) glCallList(self.tex_dl) glPopMatrix() #breaks in desktop! #glStencilFunc(GL_EQUAL,self.rank,self.rank) #glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP) #glPushMatrix() ##glLoadIdentity() #[width,height] = self.parent.get_near_plane_dims() #z = self.parent.get_start_z() #glTranslate(-width/2.0,-height/2.0,-z-0.01) #glScalef(width,height,1.0) self.draw_bc_screen() #glPopMatrix() glStencilFunc(GL_ALWAYS,1,1) glColor3f(1,1,1) if self.cube: glPushMatrix() self.draw_volume_bounds() glPopMatrix() if ( lighting ): glEnable(GL_LIGHTING) if ( cull ): glEnable(GL_CULL_FACE) if ( polygonmode[0] == GL_LINE ): glPolygonMode(GL_FRONT, GL_LINE) if ( polygonmode[1] == GL_LINE ): glPolygonMode(GL_BACK, GL_LINE) def set_slice(self,val): self.slice = val if self.axis == 'z': self.zslice = val elif self.axis == 'y': self.yslice = val elif self.axis == 'x': self.xslice = val else: self.trackslice = val self.generate_current_display_list() self.updateGL() def setAxis(self,val): self.axis = str(val).strip() if (self.inspector != None): if self.axis == 'z': self.inspector.set_sliceRange(0,self.data.get_zsize()-1) self.inspector.set_slice(self.zslice) self.axes_idx = 2 self.track = False elif self.axis == 'y': self.inspector.set_sliceRange(0,self.data.get_ysize()-1) self.inspector.set_slice(self.yslice) self.axes_idx = 1 self.track = False elif self.axis == 'x': self.inspector.set_sliceRange(0,self.data.get_xsize()-1) self.inspector.set_slice(self.xslice) self.axes_idx = 0 self.track = False elif self.axis == 'track': self.track = True self.inspector.set_sliceRange(0,self.data.get_xsize()-1) self.inspector.set_slice(self.trackslice) self.axes_idx = 3 self.loadTrackAxis() else: print "Error, unknown axis", self.axis, val self.generate_current_display_list() self.updateGL() def update_inspector(self,t3d): if not self.inspector or self.inspector ==None: self.inspector=EM3DSliceInspector(self) self.inspector.update_rotations(t3d) def get_inspector(self): if not self.inspector : self.inspector=EM3DSliceInspector(self) return self.inspector def loadTrackAxis(self): t3d = self.vdtools.getEmanMatrix() #at3d = self.cam.t3d_stack[len(self.cam.t3d_stack)-1] point = Vec3f(0,0,1) point *= 1.0/self.vdtools.getCurrentScale() point = point*t3d #if ( point[2] != 0 ): point[2] = -point[2] if len(self.axes) == 3 : self.axes.append(point) else: self.axes[3] = point def resize(self): self.vdtools.set_update_P_inv()
class EMIsosurfaceModel(EM3DModel): def eye_coords_dif(self,x1,y1,x2,y2,mdepth=True): return self.vdtools.eye_coords_dif(x1,y1,x2,y2,mdepth) def __init__(self,gl_widget, image=None,enable_file_browse=False): self.data = None EM3DModel.__init__(self, gl_widget) self.init() self.initialized = True self.cam=Camera2(self) self.tex_name = 0 self.texture = False self.brightness = 0 self.contrast = 10 self.glcontrast = 1.0 self.glbrightness = 0.0 self.rank = 1 self.inspector=None self.data_copy = None self.vdtools = EMViewportDepthTools(self) self.enable_file_browse = enable_file_browse self.force_update = False if image : self.set_data(image) # def __del__(self): # print "iso died" # pass def set_force_update(self,val=True): self.force_update = val def get_type(self): return "Isosurface" def get_emit_signals_and_connections(self): return {"set_threshold":self.set_threshold} def update_data_and_texture(self): self.data_copy = self.data.copy() self.data_copy.add(self.brightness) self.data_copy.mult(self.contrast) hist = self.data_copy.calc_hist(256,self.minden,self.maxden) self.inspector.set_hist(hist,self.minden,self.maxden) if ( self.texture ): self.gen_texture() def gen_texture(self): if ( self.texture == False ): return if ( self.tex_name != 0 ): glDeleteTextures(self.tex_name) if ( self.data_copy == None ): self.tex_name = GLUtil.gen_gl_texture(self.data) else: self.tex_name = GLUtil.gen_gl_texture(self.data_copy) def render(self): if (not isinstance(self.data,EMData)): return #a = time() lighting = glIsEnabled(GL_LIGHTING) cull = glIsEnabled(GL_CULL_FACE) depth = glIsEnabled(GL_DEPTH_TEST) polygonmode = glGetIntegerv(GL_POLYGON_MODE) normalize = glIsEnabled(GL_NORMALIZE) glEnable(GL_CULL_FACE) glCullFace(GL_BACK) #glDisable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) glEnable(GL_NORMALIZE) #glDisable(GL_NORMALIZE) if ( self.wire ): glPolygonMode(GL_FRONT,GL_LINE); else: glPolygonMode(GL_FRONT,GL_FILL); if self.light: glEnable(GL_LIGHTING) else: glDisable(GL_LIGHTING) glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1,1) glPopMatrix() self.cam.position() glShadeModel(GL_SMOOTH) if ( self.isodl == 0 or self.force_update ): self.get_iso_dl() self.force_update = False glStencilFunc(GL_EQUAL,self.rank,0) glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE) glMaterial(GL_FRONT, GL_AMBIENT, self.colors[self.isocolor]["ambient"]) glMaterial(GL_FRONT, GL_DIFFUSE, self.colors[self.isocolor]["diffuse"]) glMaterial(GL_FRONT, GL_SPECULAR, self.colors[self.isocolor]["specular"]) glMaterial(GL_FRONT, GL_SHININESS, self.colors[self.isocolor]["shininess"]) glMaterial(GL_FRONT, GL_EMISSION, self.colors[self.isocolor]["emission"]) glColor(self.colors[self.isocolor]["ambient"]) glPushMatrix() glTranslate(-self.data.get_xsize()/2.0,-self.data.get_ysize()/2.0,-self.data.get_zsize()/2.0) if ( self.texture ): glScalef(self.data.get_xsize(),self.data.get_ysize(),self.data.get_zsize()) glCallList(self.isodl) glPopMatrix() self.draw_bc_screen() glStencilFunc(GL_ALWAYS,1,1) if self.cube: glDisable(GL_LIGHTING) glPushMatrix() self.draw_volume_bounds() glPopMatrix() if ( lighting ): glEnable(GL_LIGHTING) else: glDisable(GL_LIGHTING) if ( not cull ): glDisable(GL_CULL_FACE) else: glDisable(GL_CULL_FACE) if ( depth ): glEnable(GL_DEPTH_TEST) else : glDisable(GL_DEPTH_TEST) if ( not normalize ): glDisable(GL_NORMALIZE) if ( polygonmode[0] == GL_LINE ): glPolygonMode(GL_FRONT, GL_LINE) else: glPolygonMode(GL_FRONT, GL_FILL) #if ( polygonmode[1] == GL_LINE ): glPolygonMode(GL_BACK, GL_LINE) #else: glPolygonMode(GL_BACK, GL_FILL) #print "total time is", time()-a def init(self): self.mmode = 0 self.inspector=None self.isothr=0.5 self.isorender=None self.isodl = 0 self.smpval=-1 self.griddl = 0 self.scale = 1.0 self.cube = False self.wire = False self.light = True def get_iso_dl(self): # create the isosurface display list self.isorender.set_surface_value(self.isothr) self.isorender.set_sampling(self.smpval) if ( self.texture ): if ( self.tex_name == 0 ): self.update_data_and_texture() face_z = False if self.data.get_zsize() <= 2: face_z = True if ( self.texture ): self.isodl = GLUtil.get_isosurface_dl(self.isorender, self.tex_name,face_z) else: self.isodl = GLUtil.get_isosurface_dl(self.isorender, 0,face_z) #time2 = clock() #dt1 = time2 - time1 #print "It took %f to render the isosurface" %dt1 def update_data(self,data): if data==None or (isinstance(data,EMData) and data.get_zsize()<=1) : print "Error, tried to set data that is invalid for EMIsosurface" return self.data=data self.isorender=MarchingCubes(data) self.get_iso_dl() self.updateGL() def set_data(self,data): """Pass in a 3D EMData object""" if data==None: print "Error, tried to set data that is invalid for EMIsosurface" return self.data=data if self.isodl != 0: self.force_update = True self.minden=data.get_attr("minimum") self.maxden=data.get_attr("maximum") mean=data.get_attr("mean") sigma=data.get_attr("sigma") #d = data.get_attr_dict() #x,y,z,act = 0,0,0,False #if d.has_key("origin_x"): #x = d["origin_x"]/d["apix_x"] + data.get_xsize()/2 #act = True #if d.has_key("origin_y"): #y = d["origin_y"]/d["apix_y"] + data.get_ysize()/2 #act = True #if d.has_key("origin_z"): #z = d["origin_z"]/d["apix_z"] + data.get_zsize()/2 #act = True if not self.inspector or self.inspector == None: self.inspector=EMIsoInspector(self) #if act: #self.inspector.set_xyz_trans(x,y,z) hist = data.calc_hist(256,self.minden,self.maxden) self.inspector.set_hist(hist,self.minden,self.maxden) iso_threshold = mean+3.0*sigma self.inspector.set_thresholds(self.minden,self.maxden,iso_threshold) self.isothr = iso_threshold self.brightness = -self.isothr self.isorender=MarchingCubes(data) self.inspector.set_sampling_range(self.isorender.get_sampling_range()) # nx,ny,nz = data.get_xsize(),data.get_ysize(),data.get_zsize() # if nx > 256 or ny > 256 or nz > 256: # self.isorender.set_sampling(2) self.load_colors() self.inspector.set_materials(self.colors,self.isocolor) from emglobjects import EM3DGLWidget if isinstance(self.get_gl_widget(),EM3DGLWidget): self.get_gl_widget().set_camera_defaults(self.data) def load_colors(self): self.colors = get_default_gl_colors() self.isocolor = "bluewhite" def get_material(self): return self.colors[self.isocolor] def set_threshold(self,val): if (self.isothr != val): self.isothr = val self.brightness = -val if ( self.texture ): self.update_data_and_texture() self.get_iso_dl() if self.emit_events: self.emit(QtCore.SIGNAL("set_threshold"),val) self.updateGL() def set_sample(self,val): if ( self.smpval != int(val)): # the minus two is here because the marching cubes thinks -1 is the high level of detail, 0 is the next best and so forth # However the user wants the highest level of detail to be 1, and the next best to be 2 and then 3 etc self.smpval = int(val)-2 self.get_iso_dl() self.updateGL() def set_material(self,val): #print val self.isocolor = str(val) self.updateGL() def toggle_cube(self): self.cube = not self.cube self.updateGL() def toggle_wire(self,val): self.wire = not self.wire self.updateGL() def toggle_light(self,val): self.light = not self.light self.updateGL() def toggle_texture(self): self.texture = not self.texture if ( self.texture ): self.update_data_and_texture() self.get_iso_dl() self.updateGL() def update_inspector(self,t3d): self.get_inspector().update_rotations(t3d) def get_inspector(self): if not self.inspector : self.inspector=EMIsoInspector(self,self.enable_file_browse) return self.inspector def set_contrast(self,val): self.contrast = val self.update_data_and_texture() self.updateGL() def set_brightness(self,val): self.brightness = val self.update_data_and_texture() self.updateGL() def resize(self): self.vdtools.set_update_P_inv() def get_mrc_file(self): #added by muthu return self.get_inspector().mrcfileName
class EMVolumeModel(EM3DModel): def __init__(self, gl_widget, image=None): self.data = None EM3DModel.__init__(self, gl_widget) self.init() self.initialized = True self.initializedGL= False self.inspector=None self.tex_names_list = [] # A storage object, used to remember and later delete texture names self.axes_idx = -1 self.axes = [] self.axes.append(Vec3f(1,0,0)) self.axes.append(Vec3f(0,1,0)) self.axes.append(Vec3f(0,0,1)) #self.axes.append( Vec3f(-1,0,0) ) #self.axes.append( Vec3f(0,-1,0) ) #self.add_render_axis(1,1,1) #self.add_render_axis(-1,1,1) #self.add_render_axis(-1,-1,1) #self.add_render_axis(1,-1,1) #self.add_render_axis(1,1,0) #self.add_render_axis(-1,1,0) #self.add_render_axis(-1,-1,0) #self.add_render_axis(1,-1,0) #self.add_render_axis(0,1,1) #self.add_render_axis(0,-1,1) #self.add_render_axis(1,0,1) #self.add_render_axis(-1,0,1) if image : self.set_data(image) # def __del__(self): # print "vol died" def add_render_axis(self,a,b,c): v = Vec3f(a,b,c); v.normalize() self.axes.append( v ) def eye_coords_dif(self,x1,y1,x2,y2,mdepth=True): return self.vdtools.eye_coords_dif(x1,y1,x2,y2,mdepth) def get_type(self): return "Volume" def init(self): self.data=None self.mmode=0 self.cam = Camera2(self) self.cube = False self.vdtools = EMViewportDepthTools(self) self.contrast = 1.0 self.brightness = 0.0 self.texsample = 1.0 self.glcontrast = 1.0 self.glbrightness = 0.0 self.cube = False self.tex_name = 0 self.rank = 1 self.tex_dl = 0 self.inspector=None self.force_texture_update = False self.glflags = EMOpenGLFlagsAndTools() # OpenGL flags - this is a singleton convenience class for testing texture support def update_data(self,data): self.set_data(data) self.updateGL() def set_data(self,data): """Pass in a 3D EMData object""" self.data=data if data==None: print "Error, the data is empty" return if (isinstance(data,EMData) and data.get_zsize()<=1) : print "Error, the data is not 3D" return if not self.inspector or self.inspector ==None: self.inspector=EMVolumeInspector(self) self.update_data_and_texture() from emglobjects import EM3DGLWidget if isinstance(self.get_gl_widget(),EM3DGLWidget): self.get_gl_widget().set_camera_defaults(self.data) def test_accum(self): # this code will do volume rendering using the accumulation buffer # I opted not to go this way because you can't retain depth in the accumulation buffer # Note that it only works in the z-direction glClear(GL_ACCUM_BUFFER_BIT) self.accum = True self.zsample = self.texsample*(self.data.get_zsize()) if self.tex_name == 0: print "Error, can not render 3D texture - texture name is 0" return for z in range(0,int(self.texsample*(self.data.get_zsize()))): glEnable(GL_TEXTURE_3D) glBindTexture(GL_TEXTURE_3D, self.tex_name) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP) glTexParameter(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameter(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glBegin(GL_QUADS) zz = float(z)/float(self.data.get_zsize()-1)/self.texsample glTexCoord3f(0,0,zz) glVertex3f(0,0,zz) glTexCoord3f(1,0,zz) glVertex3f(1,0,zz) glTexCoord3f(1,1,zz) glVertex3f(1,1,zz) glTexCoord3f(0,1,zz) glVertex3f(0,1,zz) glEnd() glDisable(GL_TEXTURE_3D) if ( self.accum ): glAccum(GL_ADD, 1.0/self.zsample*self.brightness) glAccum(GL_ACCUM, 1.0/self.zsample*self.contrast) glAccum(GL_RETURN, 1.0) def render(self): lighting = glIsEnabled(GL_LIGHTING) cull = glIsEnabled(GL_CULL_FACE) depth = glIsEnabled(GL_DEPTH_TEST) polygonmode = glGetIntegerv(GL_POLYGON_MODE) glDisable(GL_LIGHTING) glDisable(GL_CULL_FACE) glDisable(GL_DEPTH_TEST) glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1,1) glPopMatrix() self.cam.position() self.vdtools.store_model() # here is where the correct display list (x,y or z direction) is determined self.texture_update_if_necessary() glStencilFunc(GL_EQUAL,self.rank,0) glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE) glPushMatrix() glTranslate(-self.data.get_xsize()/2.0,-self.data.get_ysize()/2.0,-self.data.get_zsize()/2.0) glScalef(self.data.get_xsize(),self.data.get_ysize(),self.data.get_zsize()) glEnable(GL_BLEND) #glBlendEquation(GL_MAX) if self.glflags.blend_equation_supported(): glBlendEquation(GL_FUNC_ADD) glDepthMask(GL_FALSE) glBlendFunc(GL_ONE, GL_ONE) glCallList(self.tex_dl) glDepthMask(GL_TRUE) glDisable(GL_BLEND) glPopMatrix() # this is the accumulation buffer version of the volume model - it was for testing purposes # and is left here commented out incase anyone wants to investigate it in the future #glPushMatrix() #glTranslate(-self.data.get_xsize()/2.0,-self.data.get_ysize()/2.0,-self.data.get_zsize()/2.0) #glScalef(self.data.get_xsize(),self.data.get_ysize(),self.data.get_zsize()) #self.test_accum() #glPopMatrix() #breaks in desktop! #glStencilFunc(GL_EQUAL,self.rank,self.rank) #glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP) #glPushMatrix() #glLoadIdentity() #[width,height] = self.parent.get_near_plane_dims() #z = self.parent.get_start_z() #glTranslate(-width/2.0,-height/2.0,-z-0.01) #glScalef(width,height,1.0) self.draw_bc_screen() #glPopMatrix() glStencilFunc(GL_ALWAYS,1,1) if self.cube: glPushMatrix() self.draw_volume_bounds() glPopMatrix() if ( lighting ): glEnable(GL_LIGHTING) if ( cull ): glEnable(GL_CULL_FACE) if ( depth ): glEnable(GL_DEPTH_TEST) if ( polygonmode[0] == GL_LINE ): glPolygonMode(GL_FRONT, GL_LINE) if ( polygonmode[1] == GL_LINE ): glPolygonMode(GL_BACK, GL_LINE) def texture_update_if_necessary(self): t3d = self.vdtools.getEmanMatrix() point = Vec3f(0,0,1) point = point*t3d point[0] = abs(point[0]) point[1] = abs(point[1]) point[2] = abs(point[2]) #point[1] = -point[1] #if ( point[2] < 0 ): #point[2] = -point[2] #point[1] = -point[1] #point[0] = -point[0] currentaxis = self.axes_idx closest = 2*pi lp = point.length() point.normalize() idx = 0 for i in self.axes: try: angle = abs(acos(point.dot(i))) except: t3d.printme() print 'warning, there is a bug in the volume render which may cause incorrect rendering' return if (angle < closest): closest = angle self.axes_idx = idx idx += 1 if (currentaxis != self.axes_idx or self.force_texture_update): #print self.axes[self.axes_idx] self.gen_texture() def gen_texture(self): if self.glflags.threed_texturing_supported(): self.get_3D_texture() else: self.gen_2D_texture() def get_3D_texture(self): if ( self.tex_dl != 0 ): glDeleteLists( self.tex_dl, 1) self.tex_dl = glGenLists(1) if self.tex_dl == 0: print "Error, failed to generate display list" return n = self.get_dimension_size() v = self.axes[self.axes_idx] [t,alt,phi] = self.get_eman_transform(v) v1 = t*Vec3f(-0.5,-0.5,0) v2 = t*Vec3f(-0.5, 0.5,0) v3 = t*Vec3f( 0.5, 0.5,0) v4 = t*Vec3f( 0.5,-0.5,0) vecs = [v1,v2,v3,v4] total = self.texsample*n self.data.add(self.brightness) if self.contrast != 0: self.data.mult(self.contrast*1.0/total) if ( self.force_texture_update ): if self.tex_name != 0: glDeleteTextures(self.tex_name) self.tex_name = self.glflags.gen_textureName(self.data) self.force_texture_update = False if self.tex_name == 0: print "Error, can not render 3D texture - texture name is 0" return glNewList(self.tex_dl,GL_COMPILE) glEnable(GL_TEXTURE_3D) glBindTexture(GL_TEXTURE_3D, self.tex_name) glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP) glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) if ( not data_dims_power_of(self.data,2) and self.glflags.npt_textures_unsupported()): glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) else: glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glPushMatrix() glTranslate(0.5,0.5,0.5) glBegin(GL_QUADS) for i in range(0,int(self.texsample*n)): nn = float(i)/float(n)/self.texsample trans = (nn-0.5)*v for r in vecs: w = [r[0] + trans[0], r[1] + trans[1], r[2] + trans[2]] t = [w[0]+0.5,w[1]+0.5,w[2]+0.5] glTexCoord3fv(t) glVertex3fv(w) glEnd() glPopMatrix() glDisable(GL_TEXTURE_3D) glEndList() if self.contrast != 0: self.data.mult(total*1.0/self.contrast) self.data.add(-self.brightness) def get_eman_transform(self,p): if ( p[2] == 0 ): alt = 90 else : alt = acos(p[2])*180.0/pi phi = atan2(p[0],p[1]) phi *= 180.0/pi t = Transform({"type":"eman","alt":alt,"phi":phi}) return [t,alt,phi] def get_dimension_size(self): if ( self.axes_idx == 0 ): return self.data.get_xsize() elif ( self.axes_idx == 1 ): return self.data.get_ysize() elif ( self.axes_idx == 2 ): return self.data.get_zsize() else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return self.data.get_xsize() #return 0 def get_correct_dims_2d_emdata(self): if ( self.axes_idx == 0 ): return EMData(self.data.get_ysize(),self.data.get_zsize()) elif ( self.axes_idx == 1 ): return EMData(self.data.get_xsize(),self.data.get_zsize()) elif ( self.axes_idx == 2 ): return EMData(self.data.get_xsize(),self.data.get_ysize()) else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return EMData(self.data.get_xsize(),self.data.get_zsize()) def gen_2D_texture(self): if ( self.tex_dl != 0 ): glDeleteLists( self.tex_dl, 1) for i in self.tex_names_list: glDeleteTextures(i) self.tex_dl = glGenLists(1) if (self.tex_dl == 0 ): print "error, could not generate list" return glNewList(self.tex_dl,GL_COMPILE) glEnable(GL_TEXTURE_2D) n = self.get_dimension_size() v = self.axes[self.axes_idx] [t,alt,phi] = self.get_eman_transform(v) total = self.texsample*n for i in range(0,int(self.texsample*n)): nn = float(i)/float(n)/self.texsample trans = (nn-0.5)*v t.set_trans(2.0*int(n/2)*trans) if False and EMUtil.cuda_available(): # disable for the time being - big textures won't work on CPU tmp = self.data.cut_slice_cuda(t) else: tmp = self.get_correct_dims_2d_emdata() tmp.cut_slice(self.data,t,True) tmp.add(self.brightness) tmp.mult(self.contrast*1.0/total) #tmp.write_image("tmp.img",-1) # get the texture name, store it, and bind it in OpenGL tex_name = self.glflags.gen_textureName(tmp) self.tex_names_list.append(tex_name) glBindTexture(GL_TEXTURE_2D, tex_name) self.loat_default_2D_texture_parms() glPushMatrix() glTranslate(trans[0]+0.5,trans[1]+0.5,trans[2]+0.5) glRotatef(-phi,0,0,1) glRotatef(-alt,1,0,0) glBegin(GL_QUADS) glTexCoord2f(0,0) glVertex2f(-0.5,-0.5) glTexCoord2f(1,0) glVertex2f( 0.5,-0.5) glTexCoord2f(1,1) glVertex2f( 0.5, 0.5) glTexCoord2f(0,1) glVertex2f(-0.5, 0.5) glEnd() glPopMatrix() glDisable(GL_TEXTURE_2D) glEndList() # this may have been toggled (i.e. if the image contrast or brightness changed) if self.force_texture_update == True: self.force_texture_update = False def loat_default_2D_texture_parms(self): glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) if ( not data_dims_power_of(self.data,2) and self.glflags.npt_textures_unsupported()): glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) else: glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) def update_data_and_texture(self): if ( not isinstance(self.data,EMData) ): return hist = self.data.calc_hist(256,0,1.0) self.inspector.set_hist(hist,0,1.0) self.force_texture_update = True def set_contrast(self,val): self.contrast = val self.update_data_and_texture() self.updateGL() def set_brightness(self,val): self.brightness = val self.update_data_and_texture() self.updateGL() def set_texture_sample(self,val): if ( val < 0 ) : print "Error, cannot handle texture sample less than 0" return self.texsample = val self.force_texture_update = True self.updateGL() def update_inspector(self,t3d): if not self.inspector or self.inspector ==None: self.inspector=EMVolumeInspector(self) self.inspector.update_rotations(t3d) def get_inspector(self): if not self.inspector : self.inspector=EMVolumeInspector(self) return self.inspector def resize(self): self.vdtools.set_update_P_inv()
class EM3DSliceModel(EM3DModel): def __init__(self, gl_widget, image=None): self.data = None EM3DModel.__init__(self, gl_widget) self.init() self.initialized = True self.inspector = None self.axes = [] self.axes.append(Vec3f(1, 0, 0)) self.axes.append(Vec3f(0, 1, 0)) self.axes.append(Vec3f(0, 0, 1)) self.axes_idx = 2 self.track = False self.bright = 0 self.contrast = 1.0 self.busy = True if image: self.set_data(image) def set_contrast(self, val): self.contrast = val self.generate_current_display_list() self.updateGL() def set_brightness(self, val): self.bright = val self.generate_current_display_list() self.updateGL() # def __del__(self): # print "slice died" def get_type(self): return "Slice Viewer" def init(self): self.data = None self.mmode = 0 self.cam = Camera2(self) self.vdtools = EMViewportDepthTools(self) self.cube = False self.inspector = None self.tex_name = 0 self.tex_dl = 0 self.glcontrast = 1.0 self.glbrightness = 0.0 self.rank = 1 self.glflags = EMOpenGLFlagsAndTools( ) # OpenGL flags - this is a singleton convenience class for testing texture support def eye_coords_dif(self, x1, y1, x2, y2, mdepth=True): return self.vdtools.eye_coords_dif(x1, y1, x2, y2, mdepth) def update_data(self, data): if data == None: print("Error, the data is empty") return if (isinstance(data, EMData) and data.get_zsize() <= 1): print("Error, the data is not 3D") return # self.data = data.copy() # # min = self.data.get_attr("minimum") # max = self.data.get_attr("maximum") # # self.data.add(-min) # self.data.mult(1/(max-min)) self.generate_current_display_list() self.updateGL() def set_default_contrast_settings(self): min = self.data.get_attr("minimum") max = self.data.get_attr("maximum") # # self.data.add(-min) # self.data.mult(1/(max-min)) self.bright = -min if max != min: self.contrast = 1.0 / (max - min) else: self.contrast = 1 def set_data(self, data, fact=1.0): """Pass in a 3D EMData object""" self.busy = True if data == None: print("Error, the data is empty") return if (isinstance(data, EMData) and data.get_zsize() <= 1): print("Error, the data is not 3D") self.busy = False return self.data = data self.set_default_contrast_settings() if not self.inspector or self.inspector == None: self.inspector = EM3DSliceInspector(self) self.inspector.set_contrast_bright(self.contrast, self.bright) hist = self.data.calc_hist(256, 0, 1.0, self.bright, self.contrast) self.inspector.set_hist(hist, 0, 1.0) self.slice = data.get_zsize() / 2 self.zslice = data.get_zsize() / 2 - 1 if self.zslice < 0: self.zslice = 0 self.yslice = data.get_ysize() / 2 - 1 if self.yslice < 0: self.yslice = 0 self.xslice = data.get_xsize() / 2 - 1 if self.xslice < 0: self.xslice = 0 self.trackslice = self.xslice self.axis = 'z' self.inspector.set_sliceRange(0, data.get_zsize() - 1) self.inspector.set_slice(self.zslice) self.generate_current_display_list() from emglobjects import EM3DGLWidget if isinstance(self.get_gl_widget(), EM3DGLWidget): self.get_gl_widget().set_camera_defaults(self.data) if (self.tex_dl != 0): glDeleteLists(self.tex_dl, 1) self.tex_dl = 0 self.busy = False def get_eman_transform(self, p): if (p[2] == 0): alt = 90 else: alt = acos(p[2]) * 180.0 / pi phi = atan2(p[0], p[1]) phi *= 180.0 / pi return [Transform({"type": "eman", "alt": alt, "phi": phi}), alt, phi] def get_dimension_size(self): if (self.axes_idx == 0): return self.data.get_xsize() elif (self.axes_idx == 1): return self.data.get_ysize() elif (self.axes_idx == 2): return self.data.get_zsize() else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return self.data.get_xsize() #return 0 def get_correct_dims_2d_emdata(self): if (self.axes_idx == 0): return EMData(self.data.get_ysize(), self.data.get_zsize()) elif (self.axes_idx == 1): return EMData(self.data.get_xsize(), self.data.get_zsize()) elif (self.axes_idx == 2): return EMData(self.data.get_xsize(), self.data.get_ysize()) else: #print "unsupported axis" # this is a hack and needs to be fixed eventually return EMData(self.data.get_xsize(), self.data.get_zsize()) def generate_current_display_list(self): if self.busy: return if (self.tex_dl != 0): glDeleteLists(self.tex_dl, 1) self.tex_dl = glGenLists(1) if (self.tex_dl == 0): return #OpenGL is initialized yet self.gen_2D_texture() def gen_2D_texture(self): glNewList(self.tex_dl, GL_COMPILE) n = self.get_dimension_size() v = self.axes[self.axes_idx] [t, alt, phi] = self.get_eman_transform(v) nn = float(self.slice) / float(n) trans = (nn - 0.5) * v t.set_trans(n * trans) if False and EMUtil.cuda_available( ): # disable for the time being - big textures won't work on CPU tmp = self.data.cut_slice_cuda(t) else: tmp = self.get_correct_dims_2d_emdata() tmp.cut_slice(self.data, t, True) tmp.add(self.bright) tmp.mult(self.contrast) hist = tmp.calc_hist(256, 0, 1.0, self.bright, self.contrast) self.inspector.set_hist(hist, 0, 1.0) if (self.tex_name != 0): glDeleteTextures(self.tex_name) self.tex_name = 0 self.tex_name = self.glflags.gen_textureName(tmp) glEnable(GL_TEXTURE_2D) glBindTexture(GL_TEXTURE_2D, self.tex_name) #glPixelStorei(GL_UNPACK_ALIGNMENT, 1) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # if ( not data_dims_power_of(self.data,2) and self.glflags.npt_textures_unsupported()): # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) # else: # glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE) glPushMatrix() glTranslate(trans[0] + 0.5, trans[1] + 0.5, trans[2] + 0.5) glRotatef(-phi, 0, 0, 1) glRotatef(-alt, 1, 0, 0) glBegin(GL_QUADS) glTexCoord2f(0, 0) glVertex2f(-0.5, -0.5) glTexCoord2f(1, 0) glVertex2f(0.5, -0.5) glTexCoord2f(1, 1) glVertex2f(0.5, 0.5) glTexCoord2f(0, 1) glVertex2f(-0.5, 0.5) glEnd() glPopMatrix() glDisable(GL_TEXTURE_2D) glEndList() def render(self): if self.busy: return lighting = glIsEnabled(GL_LIGHTING) cull = glIsEnabled(GL_CULL_FACE) polygonmode = glGetIntegerv(GL_POLYGON_MODE) glDisable(GL_LIGHTING) glDisable(GL_CULL_FACE) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glPushMatrix() self.cam.position(True) # the ones are dummy variables atm... they don't do anything self.vdtools.update(1, 1) glPopMatrix() self.cam.position() self.vdtools.store_model() if (self.track): self.loadTrackAxis() self.generate_current_display_list() if (self.tex_dl == 0): self.generate_current_display_list() glStencilFunc(GL_EQUAL, self.rank, 0) glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE) glPushMatrix() glTranslate(-self.data.get_xsize() / 2.0, -self.data.get_ysize() / 2.0, -self.data.get_zsize() / 2.0) glScalef(self.data.get_xsize(), self.data.get_ysize(), self.data.get_zsize()) glCallList(self.tex_dl) glPopMatrix() #breaks in desktop! #glStencilFunc(GL_EQUAL,self.rank,self.rank) #glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP) #glPushMatrix() ##glLoadIdentity() #[width,height] = self.parent.get_near_plane_dims() #z = self.parent.get_start_z() #glTranslate(-width/2.0,-height/2.0,-z-0.01) #glScalef(width,height,1.0) self.draw_bc_screen() #glPopMatrix() glStencilFunc(GL_ALWAYS, 1, 1) glColor3f(1, 1, 1) if self.cube: glPushMatrix() self.draw_volume_bounds() glPopMatrix() if (lighting): glEnable(GL_LIGHTING) if (cull): glEnable(GL_CULL_FACE) if (polygonmode[0] == GL_LINE): glPolygonMode(GL_FRONT, GL_LINE) if (polygonmode[1] == GL_LINE): glPolygonMode(GL_BACK, GL_LINE) def set_slice(self, val): self.slice = val if self.axis == 'z': self.zslice = val elif self.axis == 'y': self.yslice = val elif self.axis == 'x': self.xslice = val else: self.trackslice = val self.generate_current_display_list() self.updateGL() def setAxis(self, val): self.axis = str(val).strip() if (self.inspector != None): if self.axis == 'z': self.inspector.set_sliceRange(0, self.data.get_zsize() - 1) self.inspector.set_slice(self.zslice) self.axes_idx = 2 self.track = False elif self.axis == 'y': self.inspector.set_sliceRange(0, self.data.get_ysize() - 1) self.inspector.set_slice(self.yslice) self.axes_idx = 1 self.track = False elif self.axis == 'x': self.inspector.set_sliceRange(0, self.data.get_xsize() - 1) self.inspector.set_slice(self.xslice) self.axes_idx = 0 self.track = False elif self.axis == 'track': self.track = True self.inspector.set_sliceRange(0, self.data.get_xsize() - 1) self.inspector.set_slice(self.trackslice) self.axes_idx = 3 self.loadTrackAxis() else: print("Error, unknown axis", self.axis, val) self.generate_current_display_list() self.updateGL() def update_inspector(self, t3d): if not self.inspector or self.inspector == None: self.inspector = EM3DSliceInspector(self) self.inspector.update_rotations(t3d) def get_inspector(self): if not self.inspector: self.inspector = EM3DSliceInspector(self) return self.inspector def loadTrackAxis(self): t3d = self.vdtools.getEmanMatrix() #at3d = self.cam.t3d_stack[len(self.cam.t3d_stack)-1] point = Vec3f(0, 0, 1) point *= 1.0 / self.vdtools.getCurrentScale() point = point * t3d #if ( point[2] != 0 ): point[2] = -point[2] if len(self.axes) == 3: self.axes.append(point) else: self.axes[3] = point def resize(self): self.vdtools.set_update_P_inv()
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()