How to Make Movies of Model Data
================================
If you are a modeler at COAPS and are looking for a quick reference, skip to
the :ref:`reference` section.
Creating movies and animations of our data is a straight forward process using
VisIt's scripting interface. We will interactively clik and drag to put the
view into *key frames* which we'll use to outline the path of the camera. All
of the window and camera parameters will be saved at each of these key frames
and then passed to a cubic interpolation routine providing the window
parameters between each key frame which will give the camera a smooth path
throughout its journey.
We'll go through the steps involved below, and link to appropriate
documentation for further reading.
.. _python:
Python Scripting Language
-------------------------
Everything that you can do using VisIt's GUI can also be done through a
command-line interface, much like matlab. The VisIt developers chose to create
this API using Python. Python is the most widely used scripting language in the
world, and is used in a myriad of applications - from web, and game development
to numerical analysis and image/audio processing.
* Learn more about the `Python language `_.
We are going to be using the Python interface to VisIt. The API is very well
documented. Anything you want to know will most likey be in the Pythom
Interface Manual.
* Get the `VisIt Python Interface Manual `_.
.. _movie-prep:
Prepare our Data for Rendering
------------------------------
To make a great movie there are a lot of things to consider.
* Background?
* Color Schemes?
* Lighting?
* Annotations?
* Keys and Legends?
* Axes Labels?
All of these things and more are easier to experiment with and set using VisIt's GUI. So
before we begin with the scripting to animate the video, let's make sure that
all of the legends are the right size with the right units, all the axes are
labeled, etc. Detailed information about how all of the settings that are available, and
how to edit them for your particular projects can be found in the `VisIt User's
Manual `_.
When you look at your visualization and the only left that you want to change
is to animate the camera, then you're ready to save the session.
**Remember the name and location where you save this session file.**
All the hard work you put into customizing all the settings will be saved in
this file and it will be used to load the same setting when we get ready to make
the animations.
Click **File**, and go to **Save session as...**
.. _visit-cli:
The VisIt Command-line Interface
--------------------------------
To launch visit with the command-line interface call it from the terminal
with the -cli flag. This will open VisIt with its visualization window and not
the tools panel that usually opens to the side. Anything you would have clicked
on in the panel is now going to be a command that you type into the terminal.
To launch VisIt in command-line mode, type the following command into your
terminal. ::
$ visit -cli
*Are you getting this?* ::
-bash: visit: command not found
If you didn't install VisIt in your root directory, either type in the full
path to the binary in the installation directory, or add the path to the
installation directory to your *PATH* environment variable much like we did
earlier in the :ref:`environment` section.
If the terminal gives you something simlar to this ::
Running: cli2.3.2
Running: viewer2.3.2 -host 127.0.0.1 -port 5600 -noint
Python 2.6.4 (r264:75706, Nov 4 2011, 18:19:45)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
and the rendering window pops up, then you're ready to begin the next step.
.. _getview:
VisIt Python API
----------------
There are only a few function calls that you will need to be familiar with to
make the most basic of movies.
**RestoreSession(filename, visitDir)**
This is the function you will use to load the session that was saved in the previous section.
``filename`` - Path to the session file.
``visitDir`` - 0 if you're using an absolute path, 1 if the session file is in the VisIt directory.
**GetView3D()**
We'll use this function to return to us all of the attributes which
define the current frame in the rendering window. These include things like
camera parameters, zoom, angle, etc.
**View3DAttributes()**
This will be used to give us a template of attributes to write to and save in the tuple of ``key frames``.
**EvalCubicSpline( t, weights, control_points )**
We'll be using this to generate all of the window attributes between each *key frame*.
``t`` - A time value between [0,1]
``weights`` - A tuple containing weights indicating where in the range [0,1] the control point occurs
``control_points`` - This will be the tuple of all our *key frames*
**SetView3D( view )**
Sets the view for the active visualization window
``view`` - A View3DAttributes object
We should still have the CLI running for VisIt. The first thing we want to do
is load back up all the settings and configurations we put together previously. ::
>>> RestoreSession( /Full/Path/To/Session/File, 0 )
This should take a minute to load up all the database information and settings
again. The next step is the most important part for making movies,
generating the key frames. You can have as many key frames as you want, but we
are using a cubic interpolant, so of course we must have at least 4.
Click, drag, zoom and play with your view until your happy. Then we use the
**GetView3D()** to get those attributes you just set up. ::
>>> GetView3D()
viewNormal = (0.298318, -0.577125, 0.760219)
focus = (150.5, 100.5, -135)
viewUp = (-0.282444, 0.707436, 0.647889)
viewAngle = 30
parallelScale = 228.802
nearPlane = -457.605
farPlane = 457.605
imagePan = (0, 0)
imageZoom = 1
perspective = 1
eyeAngle = 2
centerOfRotationSet = 0
centerOfRotation = (150.5, 100.5, -135)
axis3DScaleFlag = 0
axis3DScales = (1, 1, 1)
shear = (0, 0, 1)
These are the attributes we need to save! This is where the script comes in...
.. _movie_script:
The Movie Script
----------------
Open up a Python script file somewhere. We'll need to setup a template
to store all of the view attributes. ::
frame0 = View3DAttributes()
This will create a container storing all of the default view attributes in the
``frame0`` identifier. Now we copy and paste all of the information from
**GetView3D()** and store it in ``frame0`` by accessing all of the attributes
as objects. ::
frame0 = View3DAttributes()
frame0.viewNormal = (0.298318, -0.577125, 0.760219)
frame0.focus = (150.5, 100.5, -135)
frame0.viewUp = (-0.282444, 0.707436, 0.647889)
frame0.viewAngle = 30
frame0.parallelScale = 228.802
frame0.nearPlane = -457.605
frame0.farPlane = 457.605
frame0.imagePan = (0, 0)
frame0.imageZoom = 1
frame0.perspective = 1
frame0.eyeAngle = 2
frame0.centerOfRotationSet = 0
frame0.centerOfRotation = (150.5, 100.5, -135)
frame0.axis3DScaleFlag = 0
frame0.axis3DScales = (1, 1, 1)
frame0.shear = (0, 0, 1)
You replicate this process for every key frame, changing the name for
each attribute container until you're ready to make the movie. ::
frame1 = View3DAttributes()
...
...
frame2 = View3DAttributes()
...
...
Once all of the key frames have been saved, they need to be put into a tuple. ::
frames = ( frame0, frame1, frame2, ... )
The **EvalCubicSpline** routine needs weights telling it where in the range
[0,1] the key frame falls. Making them all equidistant is a great place to
start. This will have the camera fly around at a constant velocity. ::
x=[]
for i in range(7):
x.append( float(i) / float(6.) )
The only thing left to do is make the loop to create and save each frame! But before we
do that we need to specify how we want the frames saved, such as what type of
image to save, and where to save it at. We'll use the API's
SaveWindowAttributes() function. There are many other options you may want to
specify, look in the `Visit Python Manual
`_
for more information. Here are the basic attributes we'll need. ::
s = SaveWindowAttributes()
s.format = s.JPEG
s.outputToCurrentDirectory = 0
s.outputDirectory = "/Path/To/Output/Directory"
s.family = 1 # 1 if want Visit to automatically add 000, 001, to the end of file (We need this)
s.fileName = "frame" # This is the name of each frame saved ( will become frame000, frame001, etc )
s.width, s.height = 1680, 1050 # Here you can specify the resolution of your movie
SetSaveWindowAttributes(s)
Specify the number of frames you want and use it as the loop counter. Here is an example with 250
frames. ::
num_frames = 250
for i in range( num_frames ):
t = float(i) / float(num_frames - 1)
view = EvalCubicSpline( t, x, frames )
SetView3D( view )
SaveWindow()
This will create the 250 frames which constitute our movie. It should be noted
that this example is a very basic demonstration of what type of movies can be
made. Using much more of the functionality the API provides, one can create
custom time sliders, change plots mid movie, add fade ins and outs, and much
more. For more information about making movies with the VisIt API and many
other cool things that can be done check the `Scripting
`_ section of the
VisIt Wiki.
.. _ffmpeg:
Turning the frames into a Movie
-------------------------------
`ffmpeg `_ is a very powerful, open source,
video/audio processing framework. We'll be using it to merge all of the images
we just saved from the Python script into a movie. Again, all of the
information in this section and above could all be put into the same script for
a one click solution to making movies of your scientific data.
On Linux and Unix systems, ffmpeg is can be used as a command-line tool. There
are many, many flags and options you can use to customize your processing
tasks. To read about them refer the the `ffmpeg documentation
`_. Here we will look at just the few
options we'll need to use it for our needs.
Here is the basic functionality of ffmpeg ::
ffmpeg [[infile options][-i infile]]... {[outfile options] outfile}...
So let's say we generate some 250 frames from our movie script above, an
example of how we could convert it would be using ffmpeg with the following
options. ::
ffmpeg -r 7 -i frame%04d.jpeg -b 3000k -vcodec mpeg4 -an Movie.mp4
**-r**
This is the frame rate of the incoming images
**-i**
Specify the input images. We can use wildcards to specify the format
for many images. the ``%04d`` tells ffmpeg to look for files with 4 numbers
between the file name and extension. It will begin at 0 and continue counting
by 1 until it can't find any more files
**-b**
Choose the particular bitrate for our conversion. 3000k is a good choice for our needs
**-vcodec**
Specify the codec used to render the video. mpeg4 creates good quality videos at a reasonable size (15Mb for our 250 frame movie)
**-an**
Tell ffmpeg that there is no audio information and to skip the audio processing section to hasten rendering
**Movie.mp4**
Here you name the output file. The extension you use in the name will tell ffmpeg with container to use when packing the video.
After ffmpeg is finished you should have a presentation quality movie demonstrating your data.
.. _examples:
..
Some Example Animations
------------------------
.. raw:: html