"""
.. codeauthor:: Niklaus Johner <niklaus.johner@a3.epfl.ch>
This module contains functions to render movies from OpenStructure using ffmpeg
"""
from ost import *
import time
import os
__all__=('InterpolateTrajectory','MakeMovieAndCleanImageFiles','RenderTrajSimple','Fade',\
'Fades','ClipObject','AdvanceTraj','RenderFrames','Zoom','ZoomAndClip','ClipScene','Rotate')
[docs]def InterpolateTrajectory(t,nsteps):
nframes=t.GetFrameCount()
cell_sizes=[]
for i in range(nframes):
f=t.GetFrame(i)
cell_sizes.append(f.GetCellSize())
t=t.Filter(t.GetEntity().Select(''))
eh=t.GetEntity()
center=eh.GetCenterOfAtoms()
step=1./nsteps
for i in range(1,nframes):
cell_size=cell_sizes[i-1]
vl1=t.GetFramePositions(i-1)
vl2=t.GetFramePositions(i)
vl2=geom.Vec3List([geom.WrapVec3(el2,el1,cell_size) for el1,el2 in zip(vl1,vl2)])
for j in range(nsteps):
vl=vl1+j*step*(vl2-vl1)
t.AddFrame(geom.WrapVec3List(vl,center,cell_size))
t.AddFrame(vl2)
return t.Filter(eh.Select(''),first=nframes)
[docs]def MakeMovieAndCleanImageFiles(outdir,outname,nd='4',image_rate=24,quality=30,clean=False,first=0,last=0):
"""
Uses ffmpeg to encode a movie from png images
-pix_fmt yuv420p is needed to replay the movie in QuickTime
"""
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
os.system('/opt/local/bin/ffmpeg '+'-f image2 -r '+str(image_rate)+' -i '+filename+' -vcodec libx264 -pix_fmt yuv420p -crf '+str(quality)+' '+os.path.join(outdir,outname+'.avi'))
if clean:
for i in range(first,last):
os.system('rm '+os.path.join(outdir,filename % i))
return
[docs]def RenderTrajSimple(t,go,outdir,outname,width=500,height=500,first=0,last=-1,stride=1,first_index=0,nd='4'):
import time
scene=gfx.Scene()
width=500
height=500
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
if last==-1:last=t.GetFrameCount()
j=first_index
for i in range(first,last,stride):
scene.StartOffscreenMode(width,height)
t.CopyFrame(i)
go.UpdatePositions()
go.UpdateView()
scene.RequestRedraw()
scene.Export(filename % j,width,height,False)
scene.StopOffscreenMode()
j+=1
os.system('/opt/local/bin/ffmpeg '+'-f image2 -r 24 -i '+filename+' -r 24 -vb 20M '+os.path.join(outdir,outname+'.mpg'))
j=first_index
for i in range(first,last,stride):
os.system('rm '+os.path.join(outdir,filename % j))
j+=1
[docs]def Fade(go,nsteps,initial_opacity,final_opacity,outdir,outname,width=500,height=500,first_index=0,nd='4'):
scene=gfx.Scene()
step=(final_opacity-initial_opacity)/float(nsteps-1)
filename=outname+'%0'+nd+'d.png'
j=first_index
scene.StartOffscreenMode(width,height)
for i in range(nsteps):
go.SetOpacity(initial_opacity+i*step)
j=first_index+i
scene.Export(os.path.join(outdir,filename % j),width,height)
scene.StopOffscreenMode()
return
[docs]def Fades(go_list,nsteps,initial_opacity_list,final_opacity_list,outdir,outname,width=500,height=500,first_index=0,nd='4'):
scene=gfx.Scene()
step_list=[(fop-iop)/float(nsteps-1) for fop,iop in zip(final_opacity_list,initial_opacity_list)]
filename=outname+'%0'+nd+'d.png'
j=first_index
for i in range(nsteps):
scene.StartOffscreenMode(width,height)
for go,initial_opacity,step in zip(go_list,initial_opacity_list,step_list):
go.SetOpacity(initial_opacity+i*step)
j=first_index+i
scene.Export(os.path.join(outdir,filename % j),width,height)
scene.StopOffscreenMode()
return
[docs]def ClipObject(go,nsteps,initial_offset,final_offset,outdir,outname,width=500,height=500,first_index=0,nd='4'):
scene=gfx.Scene()
step=(final_offset-initial_offset)/float(nsteps-1)
filename=outname+'%0'+nd+'d.png'
j=first_index
scene.StartOffscreenMode(width,height)
for i in range(nsteps):
go.clip_offset=initial_offset+i*step
j=first_index+i
scene.Export(os.path.join(outdir,filename % j),width,height)
scene.StopOffscreenMode()
return
def ChangeDensity(go_list,nsteps,initial_density_list,final_density_list,outdir,outname,width=500,height=500,first_index=0,nd='4'):
scene=gfx.Scene()
step_list=[(fd-id)/float(nsteps-1) for fd,id in zip(final_density_list,initial_density_list)]
filename=outname+'%0'+nd+'d.png'
j=first_index
scene.StartOffscreenMode(width,height)
for i in range(nsteps):
for go,initial_density,final_density,step in zip(go_list,initial_density_list,final_density_list,step_list):
go.SetLevel(initial_density+i*step)
j=first_index+i
scene.Export(os.path.join(outdir,filename % j),width,height)
scene.StopOffscreenMode()
return
[docs]def AdvanceTraj(t,go,outdir,outname,width=500,height=500,first=0,last=-1,stride=1,first_index=0,nd='4'):
scene=gfx.Scene()
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
if last==-1:last=t.GetFrameCount()
j=first_index
for i in range(first,last,stride):
scene.StartOffscreenMode(width,height)
t.CopyFrame(i)
go.UpdatePositions()
go.UpdateView()
scene.Export(filename % j,width,height)
scene.StopOffscreenMode()
j+=1
return
[docs]def RenderFrames(nframes,outdir,outname,width,height,first_index,nd='4'):
scene=gfx.Scene()
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
j=first_index
for i in range(nframes):
scene.StartOffscreenMode(width,height)
scene.Export(filename % j,width,height)
j+=1
scene.StopOffscreenMode()
return
[docs]def Zoom(nsteps,outdir,outname,dz,width=500,height=500,first_index=0,nd='4'):
import math
step_size=(dz)/float(nsteps)
print step_size
scene=gfx.Scene()
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
scene.StartOffscreenMode(width,height)
j=first_index
for i in range(nsteps):
camera=scene.transform
camera.ApplyZAxisTranslation(step_size)
scene.transform=camera
scene.Export(filename % j, width, height)
j+=1
scene.StopOffscreenMode()
return
[docs]def ZoomAndClip(nsteps,outdir,outname,dz,initial_offset,final_offset,width=500,height=500,first_index=0,nd='4'):
import math
step_size=(dz)/float(nsteps)
step=(final_offset-initial_offset)/float(nsteps-1)
scene=gfx.Scene()
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
scene.StartOffscreenMode(width,height)
for i in range(nsteps):
j=first_index+i
camera=scene.transform
camera.ApplyZAxisTranslation(step_size)
scene.transform=camera
scene.near=initial_offset+i*step
scene.Export(filename % j, width, height)
scene.StopOffscreenMode()
return
[docs]def ClipScene(nsteps,initial_near,final_near,outdir,outname,width=500,height=500,first_index=0,nd='4',change_far=False,near_to_far=20):
scene=gfx.Scene()
step=(final_near-initial_near)/float(nsteps-1)
filename=outname+'%0'+nd+'d.png'
scene.StartOffscreenMode(width,height)
for i in range(nsteps):
j=first_index+i
scene.near=initial_near+i*step
if change_far:scene.far=scene.near+near_to_far
scene.Export(os.path.join(outdir,filename % j),width,height)
scene.StopOffscreenMode()
return
[docs]def Rotate(nsteps,outdir,outname,width=500,height=500,initial_angle=0,final_angle=6.28,axis=geom.Vec3(0, 1, 0),first_index=0,nd='4'):
import math
step_size=(final_angle-initial_angle)/float(nsteps)
print step_size
scene=gfx.Scene()
filename=os.path.join(outdir,outname+'%0'+nd+'d.png')
scene.StartOffscreenMode(width,height)
j=first_index
for i in range(nsteps):
#initial_angle+=step_size
#if initial_angle>math.pi*2:
# initial_angle-=math.pi*2
camera=scene.transform
#rot=geom.AxisRotation(axis, initial_angle)
#camera.SetRot(rot)
camera.ApplyAxisRotation(step_size,axis)
scene.transform=camera
scene.Export(filename % j, width, height)
j+=1
scene.StopOffscreenMode()
return