#!/usr/bin/python # Copyright (C) 2006 Branko Kokanovic # # DirectorBean.py: class which stores an animation # import os, sys, copy, math from xml.sax import make_parser from xml.sax.handler import ContentHandler import fracttypes, fractal # FIXME sys.path.append("..") from fract4dgui import preferences #interpolation type constants INT_LINEAR= 0 INT_LOG= 1 INT_INVLOG= 2 INT_COS= 3 def getAttrOrDefault(attrs, name, default): x = attrs.get(name) if x == None: x = default return x def getAttrOrElse(attrs, name): x = attrs.get(name) if x == None: raise ValueError( "Invalid file: Cannot find required attribute '%s'" % name) return x class KeyFrame: def __init__(self,filename,duration,stop,int_type,flags=(0,0,0,0,0,0)): self.filename = filename self.duration = duration self.stop = stop self.int_type = int_type self.flags = flags def save(self,fh): fh.write( '\t\t\n') def load_from_xml(attrs): kf = KeyFrame( getAttrOrElse(attrs,"filename"), int(getAttrOrElse(attrs,"duration")), int(getAttrOrElse(attrs,"stop")), int(getAttrOrElse(attrs,"inttype")), (int(getAttrOrDefault(attrs,"xy",0)), int(getAttrOrDefault(attrs,"xz",0)), int(getAttrOrDefault(attrs,"xw",0)), int(getAttrOrDefault(attrs,"yz",0)), int(getAttrOrDefault(attrs,"yw",0)), int(getAttrOrDefault(attrs,"zw",0)))) return kf load_from_xml=staticmethod(load_from_xml) class T: def __init__(self, compiler): self.compiler = compiler self.reset() def reset(self): self.avi_file="" self.width=640 self.height=480 self.framerate=25 self.redblue=True #keyframes is a list of KeyFrame objects self.keyframes=[] def get_fct_enabled(self): return preferences.userPrefs.getboolean("director","fct_enabled") def set_fct_enabled(self,fct_enabled): if fct_enabled: preferences.userPrefs.set("director","fct_enabled","1") else: preferences.userPrefs.set("director","fct_enabled","0") def get_fct_dir(self): return preferences.userPrefs.get("director","fct_dir") def set_fct_dir(self,dir): preferences.userPrefs.set("director","fct_dir",dir) def get_png_dir(self): return preferences.userPrefs.get("director","png_dir") def set_png_dir(self,dir): preferences.userPrefs.set("director","png_dir",dir) def get_avi_file(self): return self.avi_file def set_avi_file(self,file): if file!=None: self.avi_file=file else: self.avi_file="" def get_width(self): return self.width def set_width(self,width): if width!=None: self.width=int(width) else: self.width=640 def get_height(self): return self.height def set_height(self,height): if height!=None: self.height=int(height) else: self.height=480 def get_framerate(self): return self.framerate def set_framerate(self,fr): if fr!=None: self.framerate=int(fr) else: self.framerate=25 def get_redblue(self): return self.redblue def set_redblue(self,rb): if rb!=None: if rb==1: self.redblue=True elif rb==0: self.redblue=False self.redblue=rb else: self.redblue=True def add_keyframe(self,filename,duration,stop,int_type,index=None): kf = KeyFrame(filename,duration,stop,int_type) if index==None: self.keyframes.append(kf) else: self.keyframes.insert(index, kf) def remove_keyframe(self,index): self.keyframes[index:index+1]=[] def change_keyframe(self,index,duration,stop,int_type): if index\n') fh.write("\n") fh.write('\t\n') for kf in self.keyframes: kf.save(fh) fh.write('\t\n') fh.write('\t\n'% (self.avi_file,self.framerate,self.width,self.height,self.redblue)) fh.write("\n") fh.close() #leftover from debugging purposes def pr(self): print self.__dict__ def get_image_filename(self,n): "The filename of the image containing the Nth frame" return os.path.join(self.get_png_dir(),"image_%07d.png" %n) def get_fractal_filename(self,n): "The filename of the .fct file which generates the Nth frame" return os.path.join(self.get_fct_dir(),"file_%07d.fct" % n) def get_mu(self, int_type, x): if int_type==INT_LINEAR: mu=x elif int_type==INT_LOG: mu=math.log(x+1,2) elif int_type==INT_INVLOG: mu=(math.exp(x)-1)/(math.e-1) elif int_type==INT_COS: mu=(1-math.cos(x*math.pi))/2 else: raise ValueError("Unknown interpolation type %d" % int_type) return mu # create a list containing all the filenames of the frames def create_list(self): framelist = [] folder_png=self.get_png_dir() current=1 for i in range(self.keyframes_count()): for j in range(self.get_keyframe_stop(i)): #output keyframe 'stop' times framelist.append(self.get_image_filename(current-1)) if i < self.keyframes_count()-1: # final frame has no transitions following it for j in range(self.get_keyframe_duration(i)): #output all transition files framelist.append(self.get_image_filename(current)) current=current+1 return framelist def get_keyframe_durations(self): durations = [] for i in xrange(self.keyframes_count()): durations.append(self.get_keyframe_duration(i)) return durations def get_total_frames(self): count = 0 nframes = self.keyframes_count() for i in xrange(nframes): count += self.get_keyframe_stop(i) if i < nframes - 1: # don't count the last frame's duration count += self.get_keyframe_duration(i) return count class AnimationHandler(ContentHandler): def __init__(self,animation): self.animation=animation def startElement(self, name, attrs): if name=="output": self.animation.set_avi_file(attrs.get("filename")) self.animation.set_framerate(attrs.get("framerate")) self.animation.set_width(attrs.get("width")) self.animation.set_height(attrs.get("height")) self.animation.set_redblue(int(attrs.get("swap"))) elif name=="keyframe": kf= KeyFrame.load_from_xml(attrs) self.animation.keyframes.append(kf) return