""" python/ui/presentation.py: CCP4MG Molecular Graphics Program Copyright (C) 2001-2008 University of York, CCLRC Copyright (C) 2009-2010 University of York Copyright (C) 2012 STFC This library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3, modified in accordance with the provisions of the license to address the requirements of UK law. You should have received a copy of the modified GNU Lesser General Public License along with this library. If not, copies may be downloaded from http://www.ccp4.ac.uk/ccp4license.php This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. """ import os, sys, utils from PyQt4 import QtCore from global_definitions import * directory_ext = 'ccp4mg_presentation' SNAPSHOT_SIZE = 200 #---------------------------------------------------------------------- def open_presentation( presentation_dir='', DIR_presentation_dir='', mode='',**keywords): #---------------------------------------------------------------------- #print 'open_presentation',presentation_dir if os.path.splitext(presentation_dir)[1] == '.zip': presentation_dir = os.path.abspath(utils.get_filename(DIR_presentation_dir,presentation_dir)) rv = utils.unzip(presentation_dir) if rv[0]: MGGUI().WarningMessage('Error unpacking presentation '+presentation_dir) return None else: presentation_dir = rv[1] if presentation_dir: dir = os.path.abspath(utils.get_filename(DIR_presentation_dir,presentation_dir)) pref_file = os.path.join(dir,'preferences.pkl') if os.path.exists(dir) and os.path.exists(pref_file): action = 'open' else: # Beware in 'open' mode file browser does not add extension if os.path.splitext(dir)[1]!= '.'+directory_ext: dir = dir + '.' + directory_ext action = 'create' #print "presentation.insts",presentation.insts,exit #if sys.platform == 'win32': pref_file = utils.msvcescape(pref_file) #print "pref_file",pref_file if presentation.insts: for obj in presentation.insts: if obj.master_dir == dir: return obj #print 'presentation.open_presentation',action if action == 'open': new_presentation = presentation(master_dir= dir) status = new_presentation.unpickle_movie(file=pref_file) #print "unpickled movie project_name",new_presentation.project_name if status: MGGUI().WarningMessage('Error attempting to open movie '+dir) new_presentation.delete() return None else: new_presentation.open(mode=mode) return new_presentation elif action == 'create': dir = create_presentation_dir(dir) if dir: new_presentation=presentation(master_dir= dir) new_presentation.pickle_movie(new_presentation.movie_file) return new_presentation else: MGGUI().WarningMessage('Error attempting to create movie directory '+dir) return None else: if sys.platform == 'win32': import re pref_file = re.sub(r'/','\\',pref_file) MGGUI().WarningMessage('Error attempting to open presentation preferences file '+pref_file) del new_presentation return None #---------------------------------------------------------------------- def create_presentation_dir(presentation_dir,mode='movie'): #---------------------------------------------------------------------- # Create new directory parent,tail=os.path.split(presentation_dir) name,ext = os.path.splitext(tail) if not ext: presentation_dir =presentation_dir + directory_ext if os.path.exists(presentation_dir): MGGUI().WarningMessage('Attempting to create a '+mode+' file.\nA directory '+presentation_dir+' already exists.\n Please give an alternative NEW name for a new '+mode) return '' if not os.path.exists(parent) or not os.path.isdir(parent): MGGUI().WarningMessage('Can not create directory '+presentation_dir+ '\nParent directory does not exist') return '' try: os.mkdir(presentation_dir) except: MGGUI().WarningMessage('Error attempting to create directory\n'+presentation_dir) return '' return presentation_dir #--------------------------------------------------------------------- #--------------------------------------------------------------------- #--------------------------------------------------------------------- class presentation(): #--------------------------------------------------------------------- #--------------------------------------------------------------------- #--------------------------------------------------------------------- insts = [] saved_program_status = None default_details = { 'transform' : [ 0.0,0.0,0.0, 0.0,0.0,0.0, 0.0], 'rock_angle': 20, 'rock_axis' : 'y', 'rock_period' : 2.0, 'interpolate_time' : 1, 'interpolate_rock':0, 'interpolate_repeats':1, 'ramp_start':0, 'ramp_end':0, 'time' : 2, 'view' : 'fixed' } #'raytrace' : 0, #'render_quality' : 0} render_quality_menu = ['0','1'] render_quality_alias = ['fast','good'] directory_ext = 'ccp4mg_presentation' movie_encoder_menu = ['ffmpeg','ImageMagick convert'] movie_encoder_alias = ['ffmpeg','convert'] movie_ext_menu = ['.gif','.mpg','.mp4','.avi'] movie_encoder_size_multiple = {'ffmpeg':8,'mencoder':8,'convert':1} movie_encoder_fps = {'ffmpeg':[25,30],'mencoder':[25,30],'convert':[]} movie_encoder_formats = {'ffmpeg':('.mpg','.mp4','.avi'),'mencoder':('.mpg','.mp4','.avi'),'convert':('.gif','.mpg','.mp4','.avi')} initialisation = { 'title' : '', 'identifier' : '', 'frame_rate' : 25, 'encoder_quality' : 100, 'frame_size' : [640,480], 'antialias' : 0, 'movie_encoder' : 'ffmpeg', 'movie_ext' : '.mpg', 'save_file_format' : 'status', 'html_template' : ['','',''], 'render_quality' : 0, 'last_scene' : 0, 'last_movie_snapshot_id' : 0, 'snapshot_list' : [], 'snapshot_details' : {}, 'recorded_details' : {}, 'notes' : {}, 'gui_mode' : 'presentation', 'true_transparency' : 0, 'do_render' : 0, 'scale_fonts_and_images' : 0 } #self.mencoder_command = "-ovc xvid -xvidencopts fixed_quant=1" #---------------------------------------------------------------------- def __init__(self,master_dir='',params={},**keywords): #---------------------------------------------------------------------- #print 'presentation.init master_dir',master_dir,params self.last_frame = 0 self.current_scene = -1 self.make_frame_mode = 'status' self.animation_on = 0 self.animation_time_delay = 0.5 self.animation_rock = 0 self.master_dir = unicode(master_dir,'utf-8') self.movie_file = os.path.join(self.master_dir,'preferences.pkl') self.movie_file_root = utils.fileRoot(self.master_dir) self.pending_jobs = {} for key,value in presentation.initialisation.items(): setattr(self,key,value) if params: for key,value in params.items(): setattr(self,key,value) if self.master_dir and not self.identifier: import string self.identifier = string.split(os.path.split(master_dir)[1],'.')[0] if not self.title: self.title = self.identifier presentation.insts.append(self) self.last_restored = 0 self.snapshot_changes = {} self.interruptable = 0 # From v1.1 want ot use png files for snapshots (supported # by browsers and noe supported by Tk with Img extension # But stick with ppm for 'old' presentation directory self.snapshot_ext = '.ppm' #import glob #if len(glob.glob(os.path.join(self.master_dir,'snapshot_*.ppm')))>0: # self.snapshot_ext = '.ppm' #print "self.snapshot_ext",self.snapshot_ext def open(self,mode=''): # The open mode (which depends on how it was opened # on the GUI) takes precedence over the stored mode which was # how it was opened last time if mode: self.gui_mode = mode #------------------------------------------------------------------- def apply(self, action='',notes='', load_file='',select='',gui_mode='', index='',show_notes='',show_details='', **keywords): #------------------------------------------------------------------- #print 'presentation.apply',action if gui_mode: self.gui_mode = gui_mode if action == 'current_status': indx,backup = self.add_movie_snapshot() #print "current_status indx",indx self.pickle_movie(file = self.movie_file) return indx elif action == 'write_html': if self.html_template[1]: template_file=utils.get_filename(self.html_template[0],self.html_template[1]) else: template_file = '' rv = self.write_html(template_file=template_file) if rv[0]: MGGUI().WarningMessage(rv[1]) else: WEB().launch_browser(rv[1],internal=1) elif action == 'backup': if keywords.has_key('identifier'): self.identifier = keywords['identifier'] compress = int(keywords.get('compress',0)) self.do_backup_data_files(project=self.identifier,compress=compress) elif action == 'cleanup': import glob,re # Remove all files not currently in the snapshot list filn_list = glob.glob(os.path.join(self.master_dir,'snapshot_*'+self.snapshot_ext)) for filn in filn_list: indx = filn[-9:-4] if not self.snapshot_list.count(indx): utils.remove_file(filn) filn0 = re.sub('snapshot','status',filn) if os.path.exists(filn0): utils.remove_file(filn0) # Remove all the backup status files for mode in ['status','snapshot']: filn_list = glob.glob(os.path.join(self.master_dir,mode+'_*.*.pkl')) for filn in filn_list: utils.remove_file(filn) elif action == 'delete_movie' or action == 'delete_frame': import glob,re for scene_list in self.tmp_delete_range: for scene in scene_list: # Remove all files not currently in the snapshot list filn_list = glob.glob(os.path.join(self.master_dir,'scene_'+scene,action[7:]+'*')) for filn in filn_list: utils.remove_file(filn) del self.tmp_delete_range self.get_movie_files(update_gui=1) elif action == 'delete_all': # zap everything - probably only wise to enable for animation import glob filn_list = glob.glob(os.path.join(self.master_dir,'scene_*')) #print "presenrtation.apply clear",filn_list for filn in filn_list: utils.remove_directory(filn) self.snapshot_list = [] elif load_file: if self.snapshot_list.count(load_file): # This status is already in the movie so copy indx,backup=self.add_movie_snapshot(index='',create=0) import shutil try: shutil.copy( self.snapshot_file(load_file), self.snapshot_file(indx) ) shutil.copy( self.snapshot_file(load_file,mode='status'), self.snapshot_file(indx,mode='status') ) #GUI.GUI.insts.WarningMessage('Snapshot '+load_file+' already in '+ \ # self.movie_file_root+' so copied to '+indx) except: MGGUI().WarningMessage('Snapshot '+load_file+' already in '+ \ self.movie_file_root+' so attempting to make copy\n'+ \ 'Error attempting to make copies') else: indx = load_file self.add_movie_snapshot(index=indx,create=0) self.pickle_movie(file = self.movie_file) self.update_gui_details(indx) elif action == 'undo_selection': self.snapshot_select = [] elif select: self.snapshot_select = select elif ['restore','restore_view','restore_display'].count(action): return self.restore_status(action=action,index=index) elif ['replace'].count(action): indx,backup = self.add_movie_snapshot(index=index,save_changes='replaced') #print "replace",indx,backup if indx>0: self.update_gui_details(indx) elif ['replace_propagate'].count(action): targets = self.get_play_list(default_all=0,group_interp_ranges=0) self.handle_copy_changes(index=index) elif ['next','previous'].count(action): if len(self.snapshot_list)>0 and \ hasattr(self,'last_restored') and \ self.snapshot_list.count(self.last_restored): if action == 'next': next = self.snapshot_list.index(self.last_restored)+1 if next>=len(self.snapshot_list): next = 0 else: next = self.snapshot_list.index(self.last_restored)-1 if next<0: next = len(self.snapshot_list)-1 else: if action == 'next': next = 0 else: next = len(self.snapshot_list)-1 #print "next",next,self.snapshot_list self.last_restored = self.snapshot_list[next] self.restore_status(action='restore',index=self.snapshot_list[next]) #elif action == 'copy_changes': # self.handle_copy_changes(copy_changes=1) elif show_details: self.handle_movie_details(index=show_details) elif show_notes: #self.handle_movie_details(index=show_details) index=show_notes if not self.notes.has_key(index): self.notes[index] = {} if not self.notes[index].has_key('notes'): self.notes[index]['notes'] = ' ' notes_text = self.notes[index]['notes'] elif notes: self.notes[index]['notes']= notes elif action == 'quit': self.delete() elif action == 'preferences': if self.gui_mode == 'movie': self.define_movie_params() else: self.define_presentation_params() elif ['preview','run_auto','record'].count(action): if action == 'run_auto': action = 'preview' self.make_movie_frames(action) elif action == 'compile': self.run_compile() elif action == 'merge': self.run_compile(merge=1,compile=0) elif action == 'make': rv = self.make_movie_frames('record',compile=1) elif action == 'run_animation': if self.snapshot_details[index].has_key('animation'): ret=self.restore_status(action='restore',index=index) if ret: return molobj_list = get_dataobj(name= self.snapshot_details[index]['animation'][0]) if molobj_list and hasattr(molobj_list[0],'animation'): molobj_list[0].animation.run_animation() return 0 #---------------------------------------------------------------------- def makeCopy(self,copy_from): #---------------------------------------------------------------------- if self.snapshot_list.count(copy_from): # This status is already in the movie so create new snapshot_details # and copy the status/snapshot file indx,backup=self.add_movie_snapshot(index='',create=0) import shutil try: shutil.copy( self.snapshot_file(copy_from), self.snapshot_file(indx) ) shutil.copy( self.snapshot_file(copy_from,mode='status'), self.snapshot_file(indx,mode='status') ) #GUI.GUI.insts.WarningMessage('Snapshot '+copy_from+' already in '+ \ # self.movie_file_root+' so copied to '+indx) except: MGGUI().WarningMessage('Snapshot '+copy_from+' already in '+ \ self.movie_file_root+' so attempting to make copy\n'+ \ 'Error attempting to make copies') return [1,'Error attempting to make copy of '+copy_from] else: # Just recreate the snapshot_details for this indx indx = copy_from self.add_movie_snapshot(index=indx,create=0) return [0,indx] #---------------------------------------------------------------------- def check_status_files(self,snapshot_list=[]): #---------------------------------------------------------------------- if not snapshot_list: snapshot_list = self.snapshot_list objList=[] fileDef= {} for snapshot in self.snapshot_list: filn = self.snapshot_file(snapshot,mode='status') if filn: rv = HISTORY().get_status_data_files(filn) if rv[0]<1: return [1,snapshot] if rv[0]>0: for item in rv[1]: if not objList.count(item): objList.append(item) fileDef[item] = rv[2][item] if not objList: return [0] else: return [2,objList,fileDef] #---------------------------------------------------------------------- def edit_status_data_files(self,objList,fileDefn): #---------------------------------------------------------------------- failed = [] for snapshot in self.snapshot_list: filn = self.snapshot_file(snapshot,mode='status') if filn: status = HISTORY().edit_status_data_files(filn,1,objList,fileDefn) rv = HISTORY().write_pickle_file(filn,status) if rv: failed.append(snapshot) return failed #---------------------------------------------------------------------- def restore_status(self,action='restore',id=''): #---------------------------------------------------------------------- #print "presentation.restore_status id",id,action if utils.safeInt(id,-1)<0: return [1,'Unrecognised snapshot id'+id] self.last_restored = id filn = self.snapshot_file(id,mode=self.save_file_format) if os.path.exists(filn): format = self.save_file_format else: # try the alternative format format = ['status','mgpic'][1-['status','mgpic'].index(self.save_file_format)] filn = self.snapshot_file(index,mode=format) if not os.path.exists(filn): return [1,'Snapshot '+filn+' not found '] if format == 'status': rv = 0 if ['restore','restore_view'].count(action): rv = HISTORY().restore_view(filename=filn) if ['restore','restore_display'].count(action): rv = HISTORY().get_status_data_files(filename=filn) if rv[0]<0: return [1,'Unable to restore status from snapshot '+filn] return elif rv[0]: hints = [] if file: hints.append(os.path.split(filn)[0]) nLost,objList,fileDef,nFound = HISTORY().get_status_data_files(filn,hints) if nLost == nFound: status_new = HISTORY().edit_status_data_files(filn,1,objList,fileDef) rv = HISTORY().update_data_status(status=status_new, override_visible=0,exclude_list=['screenshot_preferences'], delay_delete=1) else: rv = HISTORY().update_data_status(filename=filn, override_visible=0,exclude_list=['screenshot_preferences'], delay_delete=1) if rv: return [1,'Unable to restore status from snapshot '+filn] else: restore_list = [] keep_current = 0 if ['restore','restore_display'].count(action): restore_list.extend(['colours','display','params']) if ['restore','restore_view'].count(action): restore_list.append('view') if ['restore_view'].count(action):keep_current=1 PD().restore_picture_definition(filename=filn,trap_errors=1,test=0, restore_list=restore_list,keep_current=keep_current, delay_delete=1) return [0,''] #------------------------------------------------------------------------- def Exit(self): #------------------------------------------------------------------------- self.pickle_movie(self.movie_file) return #------------------------------------------------------------------------ def animate(self,mode=-1): #------------------------------------------------------------------------ if mode<0: mode = 1 - self.animation_on if not mode: MAINWINDOW().removeAnimationHandler('Animation') self.animation_on = 0 else: play_list = self.get_play_list() #print "presentation.animate play_list",play_list self.animate_scene_list = [] for item in play_list: for scene in item: status = HISTORY().load_pickle_file(filename=self.snapshot_file(scene,mode='status')) self.animate_scene_list.append(status) if len(self.animate_scene_list)<2: MGGUI().WarningMessage("Need at least two scenes selected for animation") del self.animate_scene_list return # Set the initial status self.animate_scene_position = -1 self.animate_scene_incr = 1 self.animation_count = 10 self.handle_animate() MAINWINDOW().addAnimationHandler('Animation',self.handle_animate) self.animation_on = 1 #------------------------------------------------------------------------ def handle_animate(self): #------------------------------------------------------------------------ self.animation_count = self.animation_count + 1 # This assumes the animation timer is firing every 0.1s if self.animation_count < (self.animation_time_delay * 10): return self.animation_count = 0 self.animate_scene_position = self.animate_scene_position + self.animate_scene_incr # Rotate or rock? if self.animation_rock: if self.animate_scene_position<0: self.animate_scene_position=1 self.animate_scene_incr = 1 elif self.animate_scene_position>=len(self.animate_scene_list): self.animate_scene_incr = -1 self.animate_scene_position = len(self.animate_scene_list)-2 else: if self.animate_scene_position>=len(self.animate_scene_list): self.animate_scene_position = 0 #print "presentation.handle_animate animate_scene_position",self.animate_scene_position status = self.animate_scene_list[self.animate_scene_position] for data_name in status['Data_list']: if status.has_key(data_name): d_obj = get_dataobj(name=data_name) if d_obj: rv = d_obj[0].animate(status[data_name]) #print "presentation.handle_animate",d_obj[0].name,d_obj[0].visible import rebuild rebuild.UpdateDisplay() #------------------------------------------------------------------------ def make_movie_frames(self,action='',compile=0): #------------------------------------------------------------------------ # Sort out a play_list listing the snapshots to be # processed with those that are part of a glide or interpolate # grouped into a sublist play_list = self.get_play_list() if not play_list: return 1 self.make_frame_mode = action if self.make_frame_mode == 'record' and not self.do_render: #print "presentation.make_movie_frames self.frame_size",self.frame_size MAINWINDOW().setGLSize(width=self.frame_size[0],height=self.frame_size[1],save=1) MAINWINDOW().hideWindows() sleep_period = 0 elif self.make_frame_mode == 'internal': import ffmpeg_wrapper ffmpeg_wrapper.OpenMovie(self.frame_size[0],self.frame_size[1],'test.mov') sleep_period = 0 else: sleep_period = 1.0/self.frame_rate for snap_list in play_list: scene = snap_list[0] # Check for status files for snap in snap_list: if not os.path.exists( self.snapshot_file(snap,mode='status')): MGGUI().WarningMessage('Status file for snapshot '+snap+' not found') return 0 #cleanup all movie snapshots if self.make_frame_mode=='record': import glob scene_dir = os.path.join(self.master_dir,'scene_'+scene) if os.path.exists(scene_dir): for ext in ['png','gif','mpg','mp4','avi']: for file in glob.glob(os.path.join(scene_dir,'*.'+ext)) : utils.remove_file(file) else: os.mkdir(scene_dir) interrupt = self.transform( play_list = play_list, interrupt_label = 'Movie:'+self.identifier, update_method=self.make_frame, finish_method = [self.end_transform,{'compile':compile,'play_list':play_list}], label=0) return 0 #-------------------------------------------------------------------- def restore_status_0(self,status): #-------------------------------------------------------------------- import rebuild HISTORY().update_data_status(status=initial_status, exclude_list=['screenshot_preferences'],restore_all_visible=1) rebuild.UpdateDisplay() if initial_status.has_key('view'): initial_status['view'].restore() elif initial_status.has_key('view2'): MAINWINDOW().setViewParams(initial_status['view2']) #-------------------------------------------------------------------- def run_compile(self,scene_list=[],merge=0,compile=1,**keywords): #-------------------------------------------------------------------- # Need to test if this exists - beware executable may just # be on the PATH if not scene_list: import glob play_list = self.get_play_list() scene_list=[] for snap_list in play_list: snap = snap_list[0] scene_dir = os.path.join(self.master_dir,'scene_'+snap) if os.path.exists(scene_dir) and \ glob.glob(os.path.join(scene_dir,'frame*')): scene_list.append(snap) # Run a test compile which will return error code if there # are obvious problems if compile: rv = self.compile(compile=0,scene_list=scene_list) #print "presentation.run_compile rv",rv if rv[0]==-3: import string utils.remove_file(string.split(rv[1])[-1]) return elif rv[0]<0: MGGUI().WarningMessage('Aborting compiling movie..\n'+rv[1]) return try: if not self.movie_ext in self.movie_encoder_formats[self.movie_encoder]: print "RESETTING SUFFIX to", self.movie_encoder_formats[self.movie_encoder][0] self.movie_ext = self.movie_encoder_formats[self.movie_encoder][0] if len(self.movie_encoder_fps[self.movie_encoder])>0 and not self.frame_rate in self.movie_encoder_fps[self.movie_encoder]: print "RESETTING FRAME RATE to", self.movie_encoder_fps[self.movie_encoder][0] self.frame_rate = self.movie_encoder_fps[self.movie_encoder][0] except: print "problem setting suffix" if merge and not compile: # test if there are some movies to merge rv = self.merge_movies(scene_list=scene_list,overwrite=1,ext=self.movie_ext,encoder=self.movie_encoder,test=1) if rv[0]: MGGUI().WarningMessage('Aborting merging movie..\n'+rv[1]) # Ensure current status is saved self.pickle_movie(file = self.movie_file) args = ['-dir',self.master_dir.encode('utf-8'),'-master',self.movie_file.encode('utf-8'),'-scene'] for scene in scene_list: args.append(scene) args.extend(['-encoder',self.movie_encoder,'-ext',self.movie_ext]) pm = PM('movie_preferences') for item in [self.movie_encoder+'_exe']: args.extend(['-'+item,pm.get(item)]) for item in [self.movie_encoder+'_command']: cmd_args = pm.get(item) if self.movie_encoder == "ffmpeg": cmd_args += ' -r '+str(self.frame_rate) cmd_args += ' -s '+str(self.frame_size[0])+"x"+str(self.frame_size[1]) args.extend(['-'+item,cmd_args]) for item in [self.movie_encoder+'_merge_command']: args.extend(['-'+item,pm.get(item)]) #print args #print self.movie_encoder #print self.frame_size if merge : args.append('-merge') if not compile: args.append('-no_compile') #print 'run_compile pm args',pm,args label = 'For movie '+self.identifier[0:25]+'\n' if compile and merge: label = label + 'Converting frames to scene movie\nand merging scene movies' elif compile: label = label+'Converting frames to scene movies' elif merge: label = label+'Merging scene movies' if merge and len(scene_list)>1: movie_file = \ os.path.join(self.master_dir,'movie_'+scene_list[0]+'_'+scene_list[-1]+self.movie_ext) else: movie_file = \ os.path.join(self.master_dir,'scene_'+scene_list[-1],'movie'+self.movie_ext) #print os.path.join(os.environ["CCP4MG"],"bin","compile_movie") #print args rv = JOBCONTROL().start_process( name='compile_movie', command=os.path.join(os.environ["CCP4MG"],"bin","compile_movie"), args= args, interpreter = 'python', handler=[self.review_compiled_scene,{ 'movie':movie_file}], add_job_id = 1, progress= { 'TITLE' : 'Compile movie', 'HELP' : 'movies', 'LABEL' : label } ) if rv[0]: MGGUI().WarningMessage(rv[1]) return #-------------------------------------------------------------------- def handle_movie_details(self,index='',params={},**keywords): #-------------------------------------------------------------------- if not index: return details = self.snapshot_details[index] params.update(keywords) # Take snapshot quality from movie default if not details.has_key('render_quality'): details['render_quality'] = self.render_quality for key,value in self.default_details.items(): if not details.has_key(key): details[key] = value if params.has_key('transform'): details['transform'] = params['transform'] for key in ['raytrace','interpolate_rock','interpolate_repeats','ramp_start','ramp_end','render_quality']: if params.has_key(key): details[key] = int(params[key]) for key in ['rock_period','rock_angle']: if params.has_key(key): details[key] = float(params[key]) #print "presentation.handle_movie_details",index,self.snapshot_details[index] self.pickle_movie(file = self.movie_file) #----------------------------------------------------------------------- def review_compiled_scene(self,id='',**kw): #----------------------------------------------------------------------- #print "presentation.review_compiled_scene",id,kw mess = '' status = JOBCONTROL().read_log_file(id) #print "review_compiled_scene status",status if status.has_key('status') and status['status']: if status['status'] != 'FINISHED': messs = 'Error compiling movie.' if not kw.has_key('movie'): messs = 'Error compiling movie.' elif not os.path.exists(kw['movie']): mess = mess + 'Movie file '+kw['movie']+' not found.' if mess: mess = mess + ' Look in Tools->Review jobs for further information' MGGUI().WarningMessage(mess) else: self.play_movie(filename=kw['movie']) #----------------------------------------------------------------------- def get_last_frame(self,scene_dir='',ext='*'): #----------------------------------------------------------------------- ''' Initialise setup at start of recording a movie ''' # Find the last file number import glob, string, utils existing_files = glob.glob(os.path.join(scene_dir,'frame_*.'+ext)) #print "existing_files",existing_files last = 0 for file in existing_files: i = utils.safeInt(string.split \ (string.split(os.path.basename(file),'_')[-1],'.')[0],0) if ( i > last): last = i return last #----------------------------------------------------------------------- def get_movie_files(self,scene='*',update_gui=0): #----------------------------------------------------------------------- ''' Get a list of movie files ''' # Return list of movies import glob import string movie_list = [] if scene != '*': return glob.glob(os.path.join(self.master_dir,'scene_'+scene,'movie*.*')) else: for path in glob.glob(os.path.join(self.master_dir,'movie*.*')): movie_list.append(os.path.basename(path)) path_list = glob.glob(os.path.join(self.master_dir,'scene_'+scene,'movie*.*')) for path in path_list: split1 = os.path.split(path) split2= os.path.split(split1[0]) movie_list.append(split2[1]+'/'+split1[1]) return movie_list #------------------------------------------------------------------------- def pickle_movie(self,file=''): #-------------------------------------------------------------------------- import pickle if not file: file = self.movie_file try: errcode = 2 f = open(file,'w') errcode = 3 pars = self.getparams() #print 'presentation.pickle_movie',pars #pars['preferences']=PM('movie_preferences').get() pickle.dump(pars,f) errcode = 4 f.close() except: MGGUI().WarningMessage("Error saving movie control file "+file+"\nError code is "+str(errcode)) return errcode return 0 #------------------------------------------------------------------------- def unpickle_movie(self,file=''): #------------------------------------------------------------------------- import pickle pars = {} if not os.path.exists(file): MGGUI().WarningMessage("Error presentation preferences file "+file+' not found') return 1 try: err=1 f = open(file,'rU') if f: err=2 #print "f",f pars = pickle.load(f) #print "unpickle_movie pars",file,pars err=3 f.close() else: raise IOError except: print sys.exc_info() MGGUI().WarningMessage("Error reading presentation preferences file "+file+'\nError code='+str(err)) return 1 # Load the parameters from the pickle file #print 'presentation.unpickle',pars for key,value in pars.items(): setattr(self,key,value) if self.master_dir : import string if not self.identifier : self.identifier = string.split( \ os.path.split(self.master_dir)[1],'.')[0] return 0 #---------------------------------------------------------------------- def compile(self,scene_list=[],overwrite=1,compile=1,ext='gif', \ encoder='convert',preferences={}): #---------------------------------------------------------------------- ''' Compile the image files in one scene directory into a movie gif ''' try: if not self.movie_ext in self.movie_encoder_formats[self.movie_encoder]: print "RESETTING SUFFIX to", self.movie_encoder_formats[self.movie_encoder][0] self.movie_ext = self.movie_encoder_formats[self.movie_encoder][0] if len(self.movie_encoder_fps[self.movie_encoder])>0 and not self.frame_rate in self.movie_encoder_fps[self.movie_encoder]: print "RESETTING FRAME RATE to", self.movie_encoder_fps[self.movie_encoder][0] self.frame_rate = self.movie_encoder_fps[self.movie_encoder][0] except: print "problem setting suffix" #print "compile ext",ext,self.frame_size,povray #print "movie.compile scene",compile,scene_list,preferences import re,sys log = 0 spawn_mode = os.P_WAIT if len(scene_list)<1: return [-1,''] if sys.platform == 'win32': master = re.sub('/',r'\\',self.master_dir) else: master = self.master_dir # Check into scene directories and frames exist for scene in scene_list: err = '' scene_dir = os.path.join(master,'scene_'+str(scene)) if not os.path.exists(scene_dir) or not os.path.isdir(scene_dir): return [-2,"Directory does not exist "+scene_dir] last_frame = self.get_last_frame(scene_dir) if last_frame<=0: err = err + 'No frames recorded for scene '+scene+'\n' if self.is_recording_done(scene) > 0: err = err + 'Recorded frames not up to date for '+scene +'\n' if err: return [-1,err] # Create output filename scene_dir = os.path.join(master,'scene_'+str(scene_list[0])) filename = os.path.join(scene_dir,'movie'+'.'+ext.lstrip('.')) # Just return prospective file name if os.path.exists(filename): if overwrite: utils.remove_file(filename) else: return [-3,'Output movie file exists: '+filename] if not compile: # This is just a test inside ccp4mg - if all OK then the # compile will be run as a separate process return [0,filename] if sys.platform == 'win32': filename = utils.msvcescape(filename) # Run convert or mencoder to convert pngs to movie if encoder == 'convert': encoder_exe = preferences.get('convert_exe','convert') #encoder_args = preferences.get('convert_command','-quality 100') encoder_args = '-quality '+str(int(self.encoder_quality)) command = ' -delay '+str(self.frame_rate)+' '+encoder_args+' ' for scene in scene_list: command = '' command_list = [encoder_exe] scene_dir = os.path.join(master,'scene_'+scene) first_frame = 1 last_frame = self.get_last_frame(scene_dir,ext='png') for i in range(first_frame,last_frame+1): ppmfile = os.path.join(scene_dir,'frame_'+('00000'+str(i))[-6:]+ '.png') command_list.append(ppmfile) if sys.platform == 'win32': ppmfile = utils.msvcescape(ppmfile) command = command + ' ' + ppmfile output = os.path.join(scene_dir,'movie'+ext) command_list.append(output) if sys.platform == 'win32': output = utils.msvcescape(output) command = command + ' ' + output #print "convert command",command #os.system(encoder_exe+' '+command) import subprocess try: if sys.platform == 'win32': subprocess.call(command_list,shell=True) else: subprocess.call(command_list) except: return [-4,'Failed to run ImageMagick program convert successfully'] elif encoder == 'mencoder': encoder_exe = preferences.get('mencoder_exe','mencoder') #encoder_args = preferences.get('mencoder_command','-ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=1800') encoder_args = '-ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=1800' for scene in scene_list: # This is written to allow possibility of 2 runs of mencoder for com in [encoder_args]: if com: command = '' scene_dir = os.path.join(master,'scene_'+scene) command=command+'"mf://'+os.path.join(scene_dir,'*.png')+'" ' # 'fps=' + str(self.frame_rate) + command = command + \ ' -mf type=png ' + com + \ ' -o ' + os.path.join(scene_dir,'movie'+self.movie_ext) #print "mencoder command",command if sys.platform == 'win32': # Try to get path from the registry import _winreg try: reg_key = _winreg.OpenKeyEx(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\mencoder\\Current',0,_winreg.KEY_READ) except: reg_key = None if not reg_key: return [-3,'Can not find mencoder program'] binpath = _winreg.QueryValueEx(reg_key,'BinPath')[0] _winreg.CloseKey(reg_key) print "Attempting to run mencoder program:",os.path.join(binpath,'mencoder.exe') try: os.spawnl(spawn_mode,os.path.join(binpath,'mencoder.exe'),'--',command) except: print "ERROR starting mencoder" return [1,'Can not start mencoder program'] else: #print "command",command ret = os.system(encoder_exe+' '+command) if ret/512: return [1,'Can not start mencoder program'] elif encoder == 'ffmpeg': print '--------------------------------------------------' encoder_exe = preferences.get('ffmpeg_exe','ffmpeg') #encoder_args = preferences.get('ffmpeg_command','') encoder_args = '-f mpeg -vcodec mpeg1video -ar 48000 -b '+str(500000*int(self.encoder_quality))+' -ab 192000 -y' print encoder_args import glob,sys,shutil import subprocess for scene in scene_list: scene_dir = os.path.join(master,'scene_'+scene) file_list = glob.glob(os.path.join(scene_dir,'*.png')) file_list.sort() clist = [encoder_exe,'-i',os.path.normpath(os.path.join(scene_dir,'frame_%06d.png'))] clist.extend(encoder_args.strip().split()) clist.append(os.path.join(scene_dir,'movie'+self.movie_ext)) #print "ffmpeg command",clist try: if sys.platform == 'win32': subprocess.call(clist,shell=True) else: subprocess.call(clist) except: return [-4,'Failed to run ffmpeg successfully'] return [0,filename] #----------------------------------------------------------------------- def merge_movies(self,scene_list=[],overwrite=1,ext='gif',encoder='convert',preferences={},test=0): #----------------------------------------------------------------------- import os import subprocess spawn_mode = os.P_WAIT if sys.platform == 'win32': import re master = re.sub('/',r'\\',self.master_dir) else: master = self.master_dir if len(scene_list) == 1: return [0,os.path.join(master,'scene_'+scene_list[0],'movie.'+ext)] elif len(scene_list) == 0: return [2,'No scenes selected for merging'] #print "merge_movies scene_list",scene_list merged_file = os.path.normpath(os.path.join(master,'movie_'+scene_list[0]+'_'+scene_list[-1]+ext)) if os.path.exists(merged_file): if overwrite: utils.remove_file(merged_file) else: return [-3,'Output movie file exists: '+merged_file] command = '' nmerge = 0 input_files = [] for scene in scene_list: if os.path.exists( os.path.join(master,'scene_'+scene ,'movie'+ext)): nmerge = nmerge+1 file = os.path.join(master,'scene_'+scene ,'movie'+ext) input_files.append(os.path.normpath(file)) if sys.platform == 'win32': file = utils.msvcescape(file) command = command + file + ' ' if nmerge==1: return [2,'Only one movie file in selected scene - can not merge'] elif nmerge == 0: return [2,'No movie files in selected scenes - can not merge'] if test: # This is just a test inside ccp4mg - if all OK then the # compile will be run as a separate process return [0,merged_file] if encoder == 'convert': encoder_exe = preferences.get('convert_exe','convert') clist = [encoder_exe] for f in input_files: clist.append(f) clist.append(merged_file) try: if sys.platform == 'win32': subprocess.call(clist,shell=True) else: subprocess.call(clist) except: print 'Can not start ImageMagick program convert'; sys.stdout.flush() return [1,'Can not start ImageMagick program convert'] elif encoder=='mencoder': if sys.platform == 'win32': merged_file = utils.msvcescape(merged_file) encoder_exe = preferences.get('mencoder_exe','mencoder') #encoder_merge = preferences.get('mencoder_merge_command','-ovc copy') encoder_merge = '-ovc copy' command = encoder_merge + ' -o '+merged_file + ' ' + command #print "merge_movies command",command if sys.platform == 'win32': # Try to get path from the registry import _winreg try: reg_key = _winreg.OpenKeyEx(_winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\mencoder\\Current',0,_winreg.KEY_READ) except: reg_key = None if not reg_key: return [-3,'Can not find mencoder program'] binpath = _winreg.QueryValueEx(reg_key,'BinPath')[0] _winreg.CloseKey(reg_key) try: os.spawnl(spawn_mode,os.path.join(binpath,'mencoder.exe'),'--',command) except: print "ERROR starting mencoder" return [1,'Can not start mencoder program'] else: ret = os.system(encoder_exe+' '+command) if ret/512: return [1,'Can not start mencoder program'] elif encoder == 'ffmpeg': import tempfile ftmp = tempfile.NamedTemporaryFile(suffix='.mpg',delete=False) for f in input_files: fin = open(f,"rb") ftmp.write(fin.read()) fin.close() ftmp.close() try: if sys.platform == 'win32': subprocess.call(['ffmpeg','-i',ftmp.name,'-sameq',merged_file],shell=True) else: subprocess.call(['ffmpeg','-i',ftmp.name,'-sameq',merged_file]) except: return [-4,'Failed to run ffmpeg successfully'] return [0,merged_file] return [0,merged_file] def get_movie_params(self): pars = {} #--------------------------------------------------------------------------- def set_movie_params(self, params={},**keywords): #--------------------------------------------------------------------------- params.update(keywords) #print "set_movie_params",params for key in ['frame_size','frame_rate','movie_ext','movie_encoder','encoder_quality','render_quality','true_transparency','do_render','scale_fonts_and_images']: if params.has_key(key): setattr(self,key,params[key]) # Save the new parameters self.pickle_movie(file = self.movie_file) #--------------------------------------------------------------------- def get_snapshot_list(self): #--------------------------------------------------------------------- snap = [] for item in self.snapshot_list: snap.append(item) return snap #--------------------------------------------------------------------- def set_snapshot_list(self,new_list): #--------------------------------------------------------------------- self.snapshot_list = [] for item in new_list: self.snapshot_list.append(item) #--------------------------------------------------------------------- def get_snapshot_details(self,index=''): #--------------------------------------------------------------------- pars = {} if index: index_list = [index] else: index_list = self.snapshot_details.keys() #print 'get_snapshot_details index_list',index_list, for idx in index_list: pars[idx] = {} pars[idx].update(self.snapshot_details[idx]) if not self.snapshot_details[idx].has_key('transform'): pars[idx].update(presentation.default_details) return pars def snapshot_detail(self,index,key): if self.snapshot_details.has_key(index) and self.snapshot_details[index].has_key(key): if ['time','interpolate_time'].count(key): try: val = float(self.snapshot_details[index][key]) except: val = presentation.default_details[key] return val else: return self.snapshot_details[index][key] else: return presentation.default_details[key] #--------------------------------------------------------------------- def getparams(self): #--------------------------------------------------------------------- pars = {} for item in presentation.initialisation.keys(): if hasattr(self,item): pars[item] = getattr(self,item) #print "presentation.getparams",pars return pars #------------------------------------------------------------------ def setparams(self,params={},**keywords): #------------------------------------------------------------------ import string,re params.update(keywords) #print 'presentation.setparams',params # update the snapshot list order if params.has_key('snapshot_list'): self.snapshot_list = [] for item in params['snapshot_list']: self.snapshot_list.append(item) if not self.snapshot_details.has_key(item): print "WARNING snapshot_list contains item without details",item #self.snapshot_details[item] = {} #print "presentation.setparams snapshot_list",self.snapshot_list # This handles pre-2.0 data grouped by the attribute # In 2.0+ data is grouped by the snapshot for key in ['time','to_snapshot','view','display','interpolate_time']: if params.has_key(key): nn = -1 for item in self.snapshot_list: nn = nn + 1 if not self.snapshot_details.has_key(item): self.snapshot_details[item] = {} self.snapshot_details[item][key] = params[key][nn] # update the snapshot_details for given snapshot id for id,value in params.items(): #print "presentation.setparams",id,value if self.snapshot_details.has_key(id): self.snapshot_details[id].update(value) #print "presentation.setparams snapshot_details",self.snapshot_details self.pickle_movie() #------------------------------------------------------------------- def add_movie_snapshot(self,index='',create=1,copy_from=None, \ save_changes=''): #------------------------------------------------------------------- import shutil backup='' #print "add_movie_snapshot",index if save_changes and index: for mode in ['snapshot','status']: filn0 = self.snapshot_file(index,mode=mode) if os.path.exists(filn0): #Backup to filename with extension derived from epoc time backup = self.snapshot_file(index,mode=mode,version=save_changes) shutil.copyfile(filn0, backup) if not index: self.last_movie_snapshot_id = self.last_movie_snapshot_id + 1 index = str(self.last_movie_snapshot_id) index = '00000'[0:5-len(index)] + index animation = [''] if create: filn = self.snapshot_file(index) #print "add_movie_snapshot filn",filn if os.path.exists(filn): utils.remove_file(filn) size = SNAPSHOT_SIZE import screenshot screenshot.makeScreenshot(filename=filn.encode('utf-8'),size=[size,size],clear_labels=1,render_quality=0) filn0 = self.snapshot_file(index,mode=self.save_file_format) if self.save_file_format == 'status': copy_to_dir = os.path.dirname(filn0) HISTORY().save_status(filename=filn0, \ overwrite='overwrite',save_list = ['view','data','COLOUR','params','view_options'],copy_to_dir=copy_to_dir) else: PD().save_picture_definition(filename=filn0,limited_save=0) if copy_from: animation = self.snapshot_details[copy_from]['animation'] else: #Are there any animations - get the frame range import global_definitions for moldata in global_definitions.get_dataobj(object_type='MolData'): if hasattr(moldata,'animation'): animation = [moldata.name,moldata.animation.frame_range[0], moldata.animation.frame_range[1]] break #print 'Presentation.add_movie_snapshot animation',animation,index, self.snapshot_details.has_key(index) if not self.snapshot_details.has_key(index): self.snapshot_details[index] = {} self.snapshot_details[index].update(presentation.default_details) self.snapshot_details[index]['animation'] = animation self.snapshot_details[index]['to_snapshot'] =index if animation != ['']: self.snapshot_details[index]['time']= \ (float(animation[2])-float(animation[1])+1.0)/ \ float(self.frame_rate) #print 'Presentation.add_movie_snapshot time',self.snapshot_details[index]['time'] else: # Just make sure the animation status us correct self.snapshot_details[index]['animation']=animation if not self.notes.has_key(index): self.notes[index] = { 'title' : ' ', 'notes' : ' ' } #print 'presentation.add_snapshot' self.pickle_movie(self.movie_file) return index,backup #----------------------------------------------------------------------- def snapshot_file(self,index='',mode='snapshot',version=''): #----------------------------------------------------------------------- ''' Return path for file containing status or snapshot image for given index ''' if mode == 'snapshot': ext = self.snapshot_ext elif mode == 'mgpic': ext = '.py' else: ext = '.pkl' filn = os.path.join(self.master_dir,mode+'_'+str(index)) # Add the version number extension if ['new','replaced','edited'].count(version): import time,string,re t0 = string.split(time.ctime(time.time())) t1 = t0[0]+'_'+t0[2]+'_'+t0[1]+'_'+re.sub(':','_',t0[3]) filn = filn + '.' + t1 if version != 'new': filn = filn + '_' + version elif version: filn = filn + '.' + str(version) #print "snapshot_file",index,'*',mode,'*',version,'*',filn filn = filn+ext return filn #---------------------------------------------------------------------- def get_play_list(self,default_all=1,group_interp_ranges=1): #---------------------------------------------------------------------- play_list = [] details = self.snapshot_details if hasattr(self,'snapshot_select') and self.snapshot_select: if self.snapshot_list.count(self.snapshot_select[0]) and \ self.snapshot_list.count(self.snapshot_select[1]): isnap = self.snapshot_list.index(self.snapshot_select[0]) last = self.snapshot_list.index(self.snapshot_select[1])+1 else: return [] elif not default_all: return [] else: isnap = 0 last = len(self.snapshot_list) if not group_interp_ranges: for ii in range(isnap,last): play_list.append(self.snapshot_list[ii]) else: while isnap < last: snap = self.snapshot_list[isnap] #if details[snap]['display'] == 'interpolate' or \ # details[snap]['view'] == 'glide': if details[snap]['to_snapshot'] != snap and \ self.snapshot_list.count( details[snap]['to_snapshot']) and \ self.snapshot_list.index( details[snap]['to_snapshot']) > isnap: play_list.append(self.snapshot_list[isnap: self.snapshot_list.index( details[snap]['to_snapshot']) +1]) isnap = self.snapshot_list.index( details[snap]['to_snapshot']) else: play_list.append([snap]) isnap = isnap + 1 #print "snapshot_select",self.snapshot_select,"play_list",play_list return play_list #----------------------------------------------------------------------- def is_recording_done(self,snap): #----------------------------------------------------------------------- import glob scene_dir = os.path.join(self.master_dir,'scene_'+snap) if not os.path.exists(scene_dir): return -1 if not glob.glob(os.path.join(scene_dir,'frame*')): return -2 if not self.recorded_details.has_key(snap): return 1 if self.snapshot_details[snap] != self.recorded_details[snap]: #print 'is_recording_done no',self.snapshot_details[snap], self.recorded_details[snap] return 1 return 0 #---------------------------------------------------------------------- def make_frame(self,repeat=1,**keywords): #---------------------------------------------------------------------- ''' Make one frame of a movie ''' from PyQt4 import QtOpenGL current_scene = keywords.get('scene') self.last_frame = self.last_frame+1 #print "make_frame current_scene",current_scene,self.last_frame if self.make_frame_mode == 'preview': return 0 elif self.make_frame_mode == 'internal': import opengl, image_info, ffmpeg_wrapper yuv = image_info.image_info_yuv_tPtr(opengl.get_yuvdata()) #print yuv.y #print yuv.u #print yuv.v ffmpeg_wrapper.AddYUVMovieFrame(yuv) if repeat>1: n = 1 while n < repeat: n = n + 1 ffmpeg_wrapper.AddMovieFrame(yuv.y,yuv.u,yuv.v) return 0 else: #print "snapshot_details", self.snapshot_details[current_scene] filn = os.path.join(self.master_dir,'scene_'+str(current_scene), 'frame_'+('00000'+str(self.last_frame))[-6:])+'.png' if self.snapshot_details[current_scene].has_key('render_quality'): render_quality = self.snapshot_details[current_scene]['render_quality'] else: render_quality=self.render_quality # Somehow need to consider scaling text and images. if not self.do_render: # Simple Screenshot import tempfile from PyQt4 import QtGui,QtCore import screenshot import MGApplication havePixiePlugin = True try: from PixieDialog import RendererCore mainwin = MGApplication.GetMainWindow() if self.scale_fonts_and_images: # Scale text and images using rendererCore methods. oldDrawImages = mainwin.glWidget.drawImages oldDrawText = mainwin.glWidget.drawText oldDrawTextSeparately = mainwin.glWidget.drawTextSeparately mainwin.glWidget.drawImages = False mainwin.glWidget.drawText = False mainwin.glWidget.drawTextSeparately = False except: havePixiePlugin = False # After all PixieDialog is a plugin. pass doOffscreen = 1 try: screenshot_pm = PM('screenshot_preferences') doOffscreen = screenshot_pm.get('offscreen') except: doOffscreen = 0 #if QtOpenGL.QGLPixelBuffer.hasOpenGLPbuffers (): if doOffscreen: screenshot.makeScreenshot(filename=filn.encode('utf-8'),clear_labels=1,render_quality=0,hideWindows=0,use_pbuffer=True,size=[self.frame_size[0],self.frame_size[1]]) else: screenshot.makeScreenshot(filename=filn.encode('utf-8'),clear_labels=1,render_quality=0,hideWindows=0) if self.scale_fonts_and_images and havePixiePlugin: # Scale text and images using rendererCore methods. mainwin.glWidget.drawImages = oldDrawImages mainwin.glWidget.drawText = oldDrawText mainwin.glWidget.drawTextSeparately = oldDrawTextSeparately fontScaling = 1.0 if hasattr(mainwin,"savedGLSize"): fontScaling = float(self.frame_size[1])/mainwin.savedGLSize[1] renderer = RendererCore() mainwin = MGApplication.GetMainWindow() renderer.glScale = mainwin.glWidget.viewsize* mainwin.glWidget.RADIUS *2 / 60.0 labelsAndImages = renderer.renderFile(mainwin.glWidget,"dummy.tiff",filn,getGLScale=False,size=self.frame_size,current_size_in=mainwin.glWidget.size(),transparent=False,raytrace=False,smoothRibbons=False,darkInside=False,createInputFile=False,fontScaling=fontScaling) renderer.applyTextLabelsFromLabelsAndImages(labelsAndImages,filn,[255,255,255],transparent=False) else: # render! import tempfile from PyQt4 import QtGui,QtCore import MGApplication from PixieDialog import RendererCore renderer = RendererCore() f = filn if f.rfind(".")>-1: frib = f[:f.rfind(".")]+".rib" else: frib = f+".rib" ftiff_ = tempfile.mkstemp(".tiff",prefix="ccp4mg"+str(os.getpid())) ftiff = ftiff_[1] os.close(ftiff_[0]) mainwin = MGApplication.GetMainWindow() renderer.glScale = mainwin.glWidget.viewsize* mainwin.glWidget.RADIUS *2 / 60.0 # Need to sort options labelsAndImages = renderer.renderFile(mainwin.glWidget,frib,ftiff,getGLScale=False,size=self.frame_size,current_size_in=mainwin.glWidget.size(),transparent=False,raytrace=False,smoothRibbons=False,darkInside=False) renderer.runPixie(frib,ftiff,labelsAndImages,transparent=False) renderer.applyTextLabelsFromLabelsAndImages(labelsAndImages,ftiff,[255,255,255],transparent=False) fin = QtGui.QImage(ftiff) fin.save(filn) os.unlink(ftiff) if repeat>1: n = 1 while n < repeat: n = n + 1 self.last_frame = self.last_frame+1 fr = os.path.join(self.master_dir,'scene_'+str(current_scene), 'frame_'+('00000'+str(self.last_frame))[-6:])+'.png' ##NEED TO DO A COPY ************************* return 0 #----------------------------------------------------------------------- def end_transform(self,compile=0,play_list={},**kw): #----------------------------------------------------------------------- #print "presentation.end_transform",compile,play_list,kw if self.make_frame_mode == 'internal': ffmpeg_wrapper.CloseMovie() for scene in play_list: #print 'end_transform scene',scene self.recorded_details[scene[0]] = {} self.recorded_details[scene[0]].update(self.snapshot_details[scene[0]]) #print 'end_transform',self.recorded_details if not self.do_render: MAINWINDOW().setGLSize(restore=1) MAINWINDOW().hideWindows(open=1) if compile: self.run_compile(merge=1) #----------------------------------------------------------------------- def do_backup_data_files ( self,dir='',project='' ,compress=0): #----------------------------------------------------------------------- import shutil,glob,pickle import dataobj,utils if not dir: # Default is to save to the master directory dir = os.path.join(self.master_dir) else: # Cleanout or create any named directory ????? if os.path.exists(dir): shutil.rmtree(dir) if not os.path.exists(dir): try: os.mkdir(dir) except: return (1,'Error creating directory'+dir) #print 'Presentation.do_backup_data_files',dir errors = [] for indx in self.snapshot_list: filn = self.snapshot_file(index=indx,mode='status') status = HISTORY().load_pickle_file(filename=filn) if status: # Copy all data files to this directory print " Presentation.do_backup_data_files status['Data_list']", status['Data_list'] for objname in status['Data_list']: if status.has_key(objname) and \ status[objname].dataparams.has_key('filename'): rv = status[objname].copy_data_files(dir=dir,project=project) #print "Presentation.do_backup_data_files rv",rv if rv[0]: for error in rv[1]: if not errors.count(error): errors.append(error) # Save the updated status f = utils.openFile(filn,'w',overwrite='overwrite') pickle.dump(status,f) f.close() if errors: text = errors[0] for item in errors[1:]: text = text +'\n' + item return [1,text] if compress: import utils rv = utils.ZipAFile(filelist=[self.master_dir],zip_file=self.master_dir+'.zip') if rv[0]: return [1,[rv[1]]] else: return [0,'Saved presentation to '+self.master_dir+'.zip'] else: return [0,'All data files copied to '+self.master_dir] #--------------------------------------------------------------------------- def copy_changes(self,index='',oldfile='',new_index='',new_version='', \ targets=[],recreate_snapshot=1): #--------------------------------------------------------------------------- # Get the differences between the old and new version of the # index status files import shutil,pickle old_status = HISTORY().load_pickle_file(filename=oldfile) if not new_index: new_index=index filename = self.snapshot_file(index,mode='status',version=new_version) new_status = HISTORY().load_pickle_file(filename=filename) # Parameters param_diffs = old_status['params'].difference(new_status['params'].data) #print "params diffs",param_diffs #Display data diffs=HISTORY().status_difference(old_status,new_status) #print "status_difference diffs",diffs if not diffs: MGGUI().WarningMessage('No differences between '+index+ ' version '+str(version)+ '\\n and '+new_index+' version '+new_version+'\\n No changes applied') #print "targets",targets # Make sure selection does not include the original changed snapshot if targets.count(index): targets.remove(index) for indx in targets: filename = self.snapshot_file(indx,mode='status') #print "copy_changes indx",indx status = HISTORY().load_pickle_file(filename=filename) HISTORY().status_add(status,diffs[0],diffs[1],diffs[2]) if param_diffs: status['params'].add(param_diffs) backup = self.snapshot_file(indx,mode='status',version='edited') try: shutil.copy( filename,backup ) shutil.copy( os.path.splitext(filename)[0]+self.snapshot_ext, \ os.path.splitext(backup)[0]+self.snapshot_ext ) except: pass f = utils.openFile(filename,'w',overwrite=1) if f: pickle.dump(status,f) f.close() else: MGGUI().WarningMessage('Error saving updated status to '+filename) if recreate_snapshot: self.restore_status(action='restore',index=indx) # Can not use apply method to restore here as will save # the status file in add_movie_snapshot indx0,backup = self.add_movie_snapshot(index=indx) if indx0>0: self.update_gui_details(indx) else: MGGUI().WarningMessage('Error saving updated snapshot for '+indx) del status #----------------------------------------------------------------------- def write_html(self,file='',template_file=''): #----------------------------------------------------------------------- import os,utils,re #Get name for output html file backup = 0 if not file: file = os.path.join(self.master_dir,'index.html') if os.path.exists(file): root,ext = os.path.splitext(file) while backup == 0 or os.path.exists(backup_file): backup = backup + 1 backup_file = root + '_' + str(backup) + '.' + ext #Read template file if not template_file: template_file = os.path.join (os.environ["CCP4MG"],'data','presentation_template.html') if not os.path.exists(template_file): return [1,'Template file '+template_file+' does not exist'] f = utils.openFile(template_file,'r') if f: template = f.read() f.close() else: return [1,'Error reading template file '+template_file] #Parse template file rx = re.search(r'(.*)(.*)(.*)',template,re.DOTALL) #if rx: print "rx.groups",rx.groups() if not rx or len(rx.groups())!=3: return [1,'Error could not find \\n.. in template file \\n'+template_file] head,loop,tail = rx.groups() # Create the html file content content = re.sub('%TITLE%',self.title,head) for indx in self.snapshot_list: content = content + re.sub ('%REFERENCE%', self.identifier, re.sub ( '%INDEX%',indx,loop)) content = content + tail # make backup if backup>0: import shutil shutil.copyfile(file,backup_file) # Write html file f = utils.openFile(file,'w',overwrite=1) if f: try: f.write(content) f.close() except: return [1,'Error writing to file '+file] else: return [1,'Error opening file '+file] return [0,file] def setInterrupt(self): #print 'presentation.setInterrupt' self.interruptSet = 1 #------------------------------------------------------------------------ def transform ( self,play_list=[],update_method='',finish_method='',label=0,interrupt_label='',**keywords): #----------------------------------------------------------------------- self.do_label=label self.update_method = update_method self.finish_method = finish_method if interrupt_label: self.interrupt_label = interrupt_label else: self.interrupt_label = 'Transform' self.transform_play_list = play_list self.transform_scene = 0 self.interruptSet = 0 self.setup_scene_transform() MAINWINDOW().addAnimationHandler(self.interrupt_label,self.next_transform) self.interruptable = 1 #----------------------------------------------------------------------- def setup_scene_transform(self): #----------------------------------------------------------------------- #print "setup_scene_transform transform_scene",self.transform_scene interpolate_status = 1 snap_list = self.transform_play_list[self.transform_scene] scene = snap_list[0] #print "setup_scene_transform scene",snap_list,scene,self.snapshot_detail(scene,'view') # Set information for make_frame method self.last_frame = 0 # Restore the initial status initial_status = HISTORY().load_pickle_file(filename=self.snapshot_file(scene,mode='status')) self.restore_status(id=scene) import rebuild rebuild.UpdateDisplay() # Initialise parameters for Transform max_repeat=self.snapshot_detail(scene,'interpolate_repeats') period=self.snapshot_detail(scene,'time') ramp_start = self.snapshot_detail(scene,'ramp_start') ramp_end = self.snapshot_detail(scene,'ramp_end') interpolate_rock=self.snapshot_detail(scene,'interpolate_rock') transf=[[0.0,0.0,0.0, 0.0,0.0,0.0, 0.0]] transform_rock = 0 interpolate_view = [] update_objects = [] # Beware snapshot without animation has [scene]['animation']=[''] if self.snapshot_details[scene].has_key('animation') and \ self.snapshot_details[scene]['animation'][0]: update_objects.extend(get_dataobj(name= self.snapshot_details[scene]['animation'][0])) ntransparent = HISTORY().get_status_transparency(initial_status) #print 'setup_scene_transform ntransparent',ntransparent self.status_list = [[initial_status,0,ntransparent]] for snap in snap_list[1:]: stat = HISTORY().load_pickle_file(filename=self.snapshot_file(snap,mode='status')) frac_time = self.snapshot_detail(snap,'interpolate_time' ) ntransparent = HISTORY().get_status_transparency(stat) self.status_list.append([stat,frac_time,ntransparent]) if self.snapshot_detail(scene,'view') == 'rotate': transf=[[0.0,360.0,0.0, 0.0,0.0,0.0, 0.0]] elif self.snapshot_detail(scene,'view')== 'rock': rock_period = self.snapshot_detail(scene,'rock_period') transform_rock = int((period/float(rock_period))+0.5) rock_angle = self.snapshot_detail(scene,'rock_angle') transf = [[ 0.0,rock_angle,0.0, 0.0,0.0,0.0, 0.0, 0.0]] elif self.snapshot_detail(scene,'view') == 'transform': transf = [self.snapshot_detail(scene,'transform')] transform_rock = interpolate_rock elif self.snapshot_detail(scene,'view') == 'glide': transf = [] for snap in snap_list: status,view=self.read_view(filename=self.snapshot_file(snap,mode='status')) frac_time =self.snapshot_detail(snap,'interpolate_time') if status: return 1 else: interpolate_view.append([view,frac_time]) if interpolate_view: rock_centre = 0 else: rock_centre = 1 nsteps = int ( 0.5 + (period * self.frame_rate)) #print "period,frame_rate,nsteps",period,frame_rate,nsteps if nsteps<=2: nsteps = 3 if transform_rock and rock_centre: nsteps = 4 * int((nsteps+2)/4) elif transform_rock: nsteps = 2 * int((nsteps+1)/1) if max_repeat<=0: self.maxframes = 0 else: self.maxframes = nsteps*max_repeat self.vpattern = [] self.tpattern = [] self.spattern = [] if len(interpolate_view)>1: MAINWINDOW().setViewParams(interpolate_view[0][0]) time_frac_total = 0 for iv in interpolate_view[1:]: time_frac_total=time_frac_total + iv[1] for vw in range(0,len(interpolate_view)-1): ns = nsteps * (interpolate_view[vw+1][1]/time_frac_total) * \ 1.0/float(interpolate_rock+1) # number steps between each view r_start = 0 r_end = 0 if vw==0: r_start = ramp_start if vw==len(interpolate_view)-2: r_end = ramp_end self.vpattern.append([[interpolate_view[vw][0],interpolate_view[vw+1][0]], \ self.get_steps(nsteps=ns,ramp_start=r_start,ramp_end=r_end)]) if interpolate_rock: # Repeat everything in reverse for vw in range(len(interpolate_view)-1,0,-1): ns = nsteps * (interpolate_view[vw][1]/time_frac_total) * \ 1.0/float(interpolate_rock+1) # number steps between each view self.vpattern.append([[interpolate_view[vw][0],interpolate_view[vw-1][0]],\ self.get_steps(nsteps=ns)]) self.vshot = 0 self.vframe = -1 else: if not transf: transf=[[0.0,0.0,0.0, 0.0,0.0,0.0, 0.0, 0]] ns = nsteps/len(transf) for tr in transf: self.tpattern.append([tr,self.get_steps(nsteps=ns,rock=transform_rock,delta=1,centre_rock=1)]) self.tshot = 0 self.tframe = -1 #if interpolate_status: update_dataobj_list=[] #print 'transform len self.status_list',len(self.status_list) if len(self.status_list)>1: time_frac_total=0.0 for iv in self.status_list[1:]: time_frac_total=time_frac_total + iv[1] for st in range(0,len(self.status_list)-1): #print "nsteps",nsteps,"status_list[st+1][1]",status_list[st+1][1],"time_frac_total",time_frac_total ns = nsteps * (self.status_list[st+1][1]/time_frac_total) * \ 1.0/float(interpolate_rock+1) # number steps between each view update_dataobj_list=self.get_changed_objects( \ self.status_list[st][0],self.status_list[st+1][0], interpolate_status=interpolate_status) #print "Transform update_dataobj_list",update_dataobj_list # beware -- we dont have initial and final status for the following objects for item in update_objects: if not update_dataobj_list.count(item): update_dataobj_list.append([item,None,None]) if update_dataobj_list: pattern = self.get_steps(nsteps=ns,rock=0) #print "spattern",pattern self.spattern.append([update_dataobj_list,pattern]) if interpolate_rock: # 'Rock' back by reversing though the different states for st in range(len(self.status_list)-1,0,-1): ns = nsteps * (self.status_list[st][1]/time_frac_total) * \ 1.0/float(interpolate_rock+1) # number steps between each view update_dataobj_list=self.get_changed_objects( \ self.status_list[st][0],self.status_list[st-1][0], interpolate_status=interpolate_status) # beware -- we dont have initial and final status for the following objects for item in update_objects: if not update_dataobj_list.count(item): update_dataobj_list.append([item,None,None]) if update_dataobj_list: pattern = self.get_steps(nsteps=ns,rock=0) self.spattern.append([update_dataobj_list,pattern]) else: ns=nsteps for item in update_objects: update_dataobj_list.append([item,None,None]) if update_dataobj_list: self.spattern.append([update_dataobj_list,self.get_steps(nsteps=ns,rock=interpolate_rock)]) self.sshot = 0 self.sframe = -1 #print "setup_scene_transform vpattern",len(self.vpattern) #print "tpattern",len(self.tpattern),self.tpattern #print "spattern",len(self.spattern) self.iframe = -1 return 0 #---------------------------------------------------------------------------------------------------- def next_transform(self): #---------------------------------------------------------------------------------------------------- import time import rebuild #print "next_transform", self.vpattern if self.interruptSet: MAINWINDOW().removeAnimationHandler(self.interrupt_label) self.interruptSet = 0 self.interruptable = 0 return # Set up the grapics thread for transform glWidget = GLWIDGETS()[0] ntransparent = 0 self.iframe = self.iframe + 1 #print "next_transform iframe",self.iframe if self.do_label: self.label(text=str(self.iframe+1)) if self.spattern: #if interpolate_status: self.sframe = self.sframe+1 if self.sframe>=len(self.spattern[self.sshot][1]): self.sframe = 0 self.sshot = self.sshot + 1 if self.sshot>=len(self.spattern): self.sshot= 0 HISTORY().update_data_status( \ status=self.status_list[0][0],restore_all_visible=1) frac = self.spattern[self.sshot][1][self.sframe] #print "sshot frac",self.sshot,frac #if interpolate_status: for item in self.spattern[self.sshot][0]: if item[1]: ntransparent = ntransparent + item[1].nofTransparentObjects() if item[2]: ntransparent = ntransparent + item[2].nofTransparentObjects() item[0].movie_interpolation(initial_status=item[1], \ final_status=item[2],fraction=frac,step=self.sframe) #print 'ntransparent',ntransparent #if spattern or label: update_transparency = ( self.true_transparency and ntransparent>0 ) if self.spattern or self.do_label or update_transparency : if update_transparency: saved_transparency = glWidget.transparency() glWidget.setTransparency(1) rebuild.UpdateDisplay(auto_save=0) if update_transparency: glWidget.setTransparency(saved_transparency) if self.vpattern: import pygl_coord qPtr = pygl_coord.doublea(4) start_quat = pygl_coord.Quat() end_quat = pygl_coord.Quat() self.vframe = self.vframe+1 if self.vframe>=len(self.vpattern[self.vshot][1]): self.vframe = 0 self.vshot = self.vshot + 1 if self.vshot>=len(self.vpattern): self.vshot= 0 start = self.vpattern[self.vshot][0][0] end = self.vpattern[self.vshot][0][1] frac = self.vpattern[self.vshot][1][self.vframe] for ii in range(0,4):qPtr[ii]=start['quat'][ii] start_quat.Setdval(qPtr) for ii in range(0,4):qPtr[ii]=end['quat'][ii] end_quat.Setdval(qPtr) l1,l2= pygl_coord.Quat.Distance(start_quat,end_quat), pygl_coord.Quat.Distance(start_quat,-end_quat) if abs(l1)<0.01: quat = None elif l2>=l1: quat = pygl_coord.Quat().Slerp(start_quat,end_quat,frac) else: quat = pygl_coord.Quat().Slerp(start_quat,-end_quat,frac) if quat: glWidget.setQuatNoUpdate(quat) if start.has_key('rpos'): rpos = [] for j in range(0,3): rpos.append( ((1.0-frac)*start['rpos'][j])+(frac*end['rpos'][j])) glWidget.setPositionNoUpdate(rpos) if start.has_key('RADIUS'): glWidget.setZoomNoUpdate((((1.0-frac)*start['RADIUS'])+(frac*end['RADIUS']))) if start.has_key('pos'): pos = [] for j in range(0,3): pos.append( ((1.0-frac)*start['pos'][j])+(frac*end['pos'][j])) glWidget.setPositionNoUpdate(pos) if start.has_key('scale'): glWidget.setZoomNoUpdate((((1.0-frac)*start['scale'])+(frac*end['scale']))) if start.has_key('fog_near') and start.has_key('fog_far'): glWidget.setFogNearAndFar((((1.0-frac)*start['fog_near'])+(frac*end['fog_near'])),(((1.0-frac)*start['fog_far'])+(frac*end['fog_far']))) if start.has_key('slab_width') and start.has_key('slab_offset') and start.has_key('slab_enabled'): glWidget.setSlab(start['slab_enabled'],(((1.0-frac)*start['slab_width'])+(frac*end['slab_width'])),(((1.0-frac)*start['slab_offset'])+(frac*end['slab_offset']))) if self.tpattern: self.tframe = self.tframe+1 if self.tframe>=len(self.tpattern[self.tshot][1]): self.tframe = 0 self.tshot = self.tshot + 1 if self.tshot>=len(self.tpattern): self.tshot= 0 transf = self.tpattern[self.tshot][0] frac = self.tpattern[self.tshot][1][self.tframe] #print "tframe,tshot,frac,transf",tframe,tshot,frac,transf glWidget.setRotationNoUpdate(transf[0]*frac,transf[1]*frac,transf[2]*frac ) #glWidget.setPosition((transf[3]*frac,transf[4]*frac,transf[5]*frac )) #glWidget.setZoom( transf[6]*frac ) #glWidget.frame_count = str(self.iframe+1) glWidget.updateGL() glWidget.emit(QtCore.SIGNAL("PositionChanged"),(glWidget)) glWidget.emit(QtCore.SIGNAL("QuatChanged"),(glWidget)) glWidget.emit(QtCore.SIGNAL("ZoomChanged"),(glWidget)) #self.update_dependents('transform') if self.update_method: rv = self.update_method(scene=self.transform_play_list[self.transform_scene][0]) if self.maxframes and self.iframe>= self.maxframes-1: if self.do_label: self.label(delete=1) MAINWINDOW().removeAnimationHandler(self.interrupt_label) self.interruptable = 0 if self.transform_scene < len(self.transform_play_list)-1: self.transform_scene = self.transform_scene + 1 self.setup_scene_transform() MAINWINDOW().addAnimationHandler(self.interrupt_label,self.next_transform) elif self.finish_method: DISPLAYTABLE().update() apply(self.finish_method[0],[],self.finish_method[1]) #-------------------------------------------------------------------- def get_steps(self,nsteps=1,rock=0,centre_rock=0,delta=0,mode='', \ ramp_start=0, ramp_end=0): #-------------------------------------------------------------------- ramp_start=2*(ramp_start/2) ramp_end=2*(ramp_end/2) #print "get_steps",ramp_start,ramp_end,rock tmp = [] if mode == 'sine': import math,copy last_phase = 0.0 if rock: f = 2.0 else: f= 1.0 for step in range (1,nsteps+1): phase = math.sin ( float(step) * math.pi * f / nsteps ) if delta: tmp.append(phase-last_phase) else: tmp.append(phase) last_phase=copy.deepcopy(phase) else: ns = int(nsteps/(rock+1)) #print 'get_steps ns',ns if rock and centre_rock: if delta: frac = 1.0/float(ns) for i in range(0,ns/2): tmp.append(-frac) for i in range(0,ns): tmp.append(frac) for i in range(0,ns/2): tmp.append(-frac) else: for i in range(ns/2,-1,-1): tmp.append(float(i)/float(ns)) for i in range(0,ns): tmp.append(float(i)/float(ns)) for i in range(ns,ns/2,-1): tmp.append(float(i)/float(ns)) else: if ramp_start+ramp_end>0: inc = 1.0/(float(ns-(ramp_start+ramp_end))+ \ 0.5*float(ramp_start+ramp_end)) else: inc = 1.0/float(ns) if delta: for i in range(0,ns): tmp.append(inc) if rock: for i in range(0,ns): tmp.append(-inc) else: frac = 0.0 if ramp_start: for i in range(1,ramp_start+1): tmp.append(frac) #print "i",i,float(i-1)/float(ramp_start),frac frac=frac+(inc*float(i)/float(ramp_start)) for i in range(ramp_start+1,ns-ramp_end+1): frac=frac+inc #print "i",i,frac tmp.append(frac) if ramp_end: for i in range(ns-ramp_end+1,ns+1): frac=frac+(inc*float(ns-i)/float(ramp_end)) #print "i",i,float(ns-i)/float(ramp_end),frac tmp.append(frac) if rock: for i in range(ns-1,-1,-1): tmp.append(tmp[i]) #print 'get_steps',nsteps,tmp if rock>1: for nn in range(2,rock+1): for i in range(0,ns): tmp.append(tmp[i]) #print "tmp",tmp return tmp #------------------------------------------------------------------------ def get_changed_objects(self,initial_status,final_status, interpolate_status=1): #------------------------------------------------------------------------ changed_list = [] #print "transform.get_changed_objects interpolate_status",interpolate_status,initial_status.keys(),final_status.keys() if interpolate_status: # Get list of ShadowDataObj which have changed between the initial and final status # and convert this to list of names difobj_list = HISTORY().status_difference(initial_status,final_status)[0] difobj_name_list = [] for item in difobj_list: difobj_name_list.append(item.name) #print 'presentation.get_changed_objects',difobj_name_list # Create list with one item for each currently loaded dataobj # Each item in list is [dataobj, dataobj_initial_status, dataobj_final_status] # The dataobj_initial_status and dataobj_final_status are None if there arew no changes import dataobj for item in dataobj.get_dataobj(): if difobj_name_list.count(item.name): changed_list.append([item,initial_status[item.name],final_status[item.name]]) else: changed_list.append([item,None,None]) #print 'presentation.get_changed_objects changed_list',changed_list ''' import dataobj for item in dataobj.get_dataobj(): if initial_status.has_key(item.name) and \ final_status.has_key(item.name): initial_obj = initial_status[item.name] final_obj = final_status[item.name] if initial_obj == final_obj: #print "transform.get_changed_objects initial and final status identical for",item changed_list.append( [item,None,None]) else: changed_list.append([item,initial_obj,final_obj]) ''' if initial_status.has_key('COLOUR') and final_status.has_key('COLOUR'): diffs = MGCOLOUR().compare_objects( \ initial_status['COLOUR'],final_status['COLOUR']) #print "COLOUR diffs",diffs if diffs[0]: changed_list.append([MGCOLOUR(),diffs[0],diffs[1]]) if initial_status.has_key('params') and final_status.has_key('params'): import services for key in initial_status['params'].data.keys(): if final_status['params'].data.has_key(key) and services.PM(key): diffs=services.PM(key).compare_objects( \ initial_status['params'].data[key], \ final_status['params'].data[key]) #print "diffs",key,diffs if diffs[0]: changed_list.append([services.PM(key),diffs[0],diffs[1]]) #print "transform.get_changed_objects changed_list",changed_list return changed_list #------------------------------------------------------------------------ def read_view(self,filename=''): #------------------------------------------------------------------------ ''' Read the view from a status file ''' import pickle params={} if not os.path.exists(filename): return [1,params] try: f = open(filename,'r') except: return [1,params] try: status = pickle.load(f) except: return [2,params] if status.has_key('view'): for key in ['rpos','RADIUS','NEAR','FAR','quat']: params[key] = getattr(status['view'],key) return [0,params] elif status.has_key('view2'): #print "transform.read_view",status['view2'] for key in ['pos','scale','quat','fog_far','fog_near','slab_width','slab_offset','slab_enabled']: params[key] = status['view2'].get(key) return [0,params] return [3,params] #----------------------------------------------------------------- def label(self,text='transform label',delete=0): #------------------------------------------------------------------ import build,cprim,pygl_coord,graphicsmodel #print "transform::label",text if delete: #if hasattr(self,'label_graphmod') and self.label_graphmod: # build.build.insts.deletemod(self.label_graphmod) # del self.label_graphmod # del self.label_graphmod_obj return else: if not hasattr(self,'label_graphmod') or not self.label_graphmod: import build self.label_graphmod = graphicsmodel.graphicsmodel( ) build.build.insts.append(self.label_graphmod) if hasattr(self,'label_graphmod_obj') and len(self.label_graphmod_obj)>0: for obj in self.label_graphmod_obj: cprim.DeleteTextLabel(self.label_graphmod.obj,obj.GetID()) self.label_graphmod_obj = [] x,y=0.1,0.9 label_ob = cprim.BillBoardText( \ pygl_coord.Cartesian(x,y,0.0), \ text, pygl_coord.Cartesian(x,y,0.0)) label_ob.thisown = 0 self.label_graphmod.obj.add_text_primitive(label_ob) self.label_graphmod_obj.append(label_ob) self.label_graphmod.obj.rebuild() font = DT().viewmenu.default_font self.label_graphmod.obj.SetTextFont(str(font['family']),str(font['weight']), \ str(font['slant']),'24',font['underline']) #------------------------------------------------------------------- def play_movie(self,filename): #------------------------------------------------------------------- import os from PyQt4 import QtGui,QtCore image_formats_c = QtGui.QMovie.supportedFormats() image_formats = [] for im in image_formats_c: if not image_formats.count(str(im).lower()): image_formats.append(str(im)) if os.path.exists(filename): name_split = os.path.splitext(filename) if len(name_split)>1 and '.' in name_split[1] and image_formats.count(name_split[1][1:]): viewer = FILEVIEWER(self.identifier) viewer.open(filename,format='movie',title=filename) else: if sys.platform == 'linux2': viewer = FILEVIEWER(self.identifier) viewer.open(filename,format='movie_phonon',title=filename) else: QtGui.QDesktopServices.openUrl(QtCore.QUrl.fromLocalFile(filename)) #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- class movie_preferences: #------------------------------------------------------------------- #------------------------------------------------------------------- #------------------------------------------------------------------- insts = None #------------------------------------------------------------------- def __init__(self): #------------------------------------------------------------------- movie_preferences.insts = self self.PM = self.create_movie_preferences() #------------------------------------------------------------------- def movie_preferences(self): #------------------------------------------------------------------- return self.PM #------------------------------------------------------------------------- def create_movie_preferences(self): #------------------------------------------------------------------------- import services return services.ParamsManager ( name='movie_preferences', help = 'movies#movies', title='Movie Compile', gui =['convert_exe','ffmpeg_exe','mencoder_exe','player_exe','show_progress'], default = { 'convert_command' : '-quality 100', 'ffmpeg_command' : '-f mpeg -vcodec mpeg1video -ar 48000 -b 7000000 -ab 192000 -y', 'mencoder_command' : '-ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=1800', 'mencoder_merge_command' : '-ovc copy', 'player_command' : '-loop 0', 'convert_exe' : 'convert', 'ffmpeg_exe' : 'ffmpeg', 'mencoder_exe' : 'mencoder', 'player_exe' : 'mplayer', 'show_progress' : 1 }, definition = { \ 'convert_exe' : dict(type=str,label='Convert executable(Imagemagick)'), 'convert_command' : dict(type=str,label='Convert arguments'), 'ffmpeg_exe' : dict(type=str,label='Ffmpeg executable'), 'ffmpeg_command' : dict(type=str,label='Ffmpeg arguments'), 'mencoder_exe' : dict(type=str,label='mencoder executable'), 'mencoder_command': dict(type=str,label='Mencoder arguments'), 'mencoder_merge_command': dict(type=str,label='Mencoder merge arguments'), 'player_exe' : dict(type=str,label='mpeg player executable'), 'player_command' : dict(type=str,label='mpeg player arguments'), 'show_progress' : dict(type='bool',label='Show progress',style='checkbox') })