#!/bin/csh -f
#
#                           Copyright 1991 - 1999
#                The Regents of the University of California.
#                            All rights reserved.
#
#This work was produced at the University of California, Lawrence
#Livermore National Laboratory (UC LLNL) under contract no.  W-7405-ENG-48
#(Contract 48) between the U.S. Department of Energy (DOE) and The Regents
#of the University of California (University) for the operation of UC LLNL.
#Copyright is reserved to the University for purposes of controlled
#dissemination, commercialization through formal licensing, or other
#disposition under terms of Contract 48; DOE policies, regulations and
#orders; and U.S. statutes.  The rights of the Federal Government are
#reserved under Contract 48 subject to the restrictions agreed upon by
#DOE and University.
#
#                                DISCLAIMER
#
#This software was prepared as an account of work sponsored by an agency
#of the United States Government. Neither the United States Government
#nor the University of California nor any of their employees, makes any
#warranty, express or implied, or assumes any liability or responsiblity
#for the accuracy, completeness, or usefullness of any information,
#apparatus, product, or process disclosed, or represents that its use
#would not infringe privately owned rights. Reference herein to any
#specific commercial products, process, or service by trade name, trademark,
#manufacturer, or otherwise, does not necessarily constitute or imply its
#endorsement, recommendation, or favoring by the United States Government
#or the University of California. The views and opinions of authors
#expressed herein do not necessarily state or reflect those of the United
#States Government or the University of California, and shall not be used
#for advertising or product endorsement purposes.
#

######################################################################
# 
#  Purpose:  This script takes parameter files generated by meshtv and
#            uses them to create rgb or tiff images, or mpeg movies. 
# 
#  Programmer:  Brad Whitlock
#  Date:  July 1998
# 
#  Modifications:
#      Brad Whitlock, Mon Oct 12 9:28:32 PDT 1998
#      I changed the script so it would give the mpeg movie an ".mpeg"
#      file extension. I also added logic to send signals back to the 
#      gui to have it bring up dialog boxes when the script is done.
#
#      Brad Whitlock, Sat Oct 17 17:26:23 PDT 1998
#      I removed unnecessary command line arguments from the script. 
#      I also added code to make the script check for files that it 
#      might overwrite. If any such files are found then, they are
#      moved into a new subdirectory.
# 
#      Brad Whitlock, Fri Nov 20 11:42:34 PDT 1998
#      I added more error checking to the script and also made it
#      work no matter where it is executed. This involved passing 
#      the name of the meshtvx executable since it varies. I added 
#      more smarts to the script so that it will not try to signal
#      the gui if the gui was terminated.
#
#      Brad Whitlock, Wed Nov 25 10:14:34 PDT 1998
#      Added code that will launch meshtvx with mpirun if meshtv is
#      running in parallel.
#
#      Lisa J. Roberts, Tue Dec 15 10:00:08 PST 1998
#      Changed the message informing the user that the script is done
#      so that the extension of the output file name is mpeg rather
#      than mpg.  That way it matches the real file name.  I changed
#      the sleep time to 2 to prevent race conditions with the two
#      signals which must be sent to the GUI.  I also extended the
#      help message which is put out when the user calls the script
#      incorrectly.  I changed the script so that if the meshtvx
#      executable is just "meshtvx", then we find the path to it.
#      Added support to output TIFF files in addition to RGB files.
#
#      Brad Whitlock, Wed Jun 16 9:36:45 PDT 1999
#      Changed the "parallel" argument to the "-np" argument so the 
#      number of processors can be passed on the command line. That
#      way, we don't just assume some number.
#
#      Jeremy Meredith, Tue Jul 27 16:35:25 PDT 1999
#      Added the ability to specify a full command to launch meshtvx in
#      parallel instead of -np # and assuming use of mpirun.
#
#      Brad Whitlock, Mon Nov 15 13:04:53 PST 1999
#      I added code to make the script exit with a warning message if
#      the MESHTVHOME environment variable is not set when we are
#      generating an MPEG movie.
#
#      Brad Whitlock, Mon Dec 13 11:12:27 PDT 1999
#      Changed code so the script properly signals the MeshTV GUI
#      when running on OS's whose ps command prints command line
#      arguments in the process list. This includes Linux, and OSF1.
#
#      Brad Whitlock, Tue May 23 12:01:39 PDT 2000
#      Added support for non-square movies.
#
######################################################################

# Check for improper usage
if(($#argv != 5 ) && ($#argv != 6) && ($#argv != 7) && ($#argv != 8)) then
    echo "Usage: movie_generate  filebase outputmode width height"
    echo "                       meshtvx [gui_pid] [-np # | -launch command]"
    echo ""
    echo "where filebase is the base name of the file, outputmode"
    echo "is either rgb, tiff, or mpeg. Width is an integer number"
    echo "of pixels in the horizontal direction. Height is an integer"
    echo "number of pixels in the vertical direction. Meshtvx is the"
    echo "full path to the meshtvx executable (including the meshtvx"
    echo "name), gui_pid is the process id of the GUI when this"
    echo "script is run from the GUI, and -np, when included,"
    echo "means that meshtvx should be run in parallel with"
    echo "the specified number of processors."
    exit
endif

# get directory, environment, OS information
set CURRENTDIR = `pwd|awk '{printf "%s", $1}'`
set MESHTVHOME = `env|fgrep 'MESHTVHOME='|awk '{printf substr($1,12,length-11)}'`
set OS_NAME = `uname | awk '{printf substr($1, 1, 4)}'`

# If the OS name is IRIX, then the ps command probably does not print
# the command line arguments for processes in the list. Other OS's
# like Linux and OSF1 tend to do that.
if("$OS_NAME" == "IRIX") then
    set ps_prints_args = 0
else
    set ps_prints_args = 1
endif

#
# set some variables from the command line arguments  
#
set filebase        = $CURRENTDIR/$argv[1]
set outputmode      = $argv[2]
set width           = $argv[3]
set height          = $argv[4]

# set some global variables that hold names of the converter programs
set MPEGCONV = $MESHTVHOME/bin/mpeg_encode
set MESHTVX  = $argv[5]

# set some defaults
set called_from_gui = 0
set running_parallel = 0
set np_count = 1
set launch_command = ""
set launch_command_given = 0

#
# If the Gui's pid was passed, then get it. Also determine if we want
# to run with parallel MeshTV.
#

if ($#argv == 6) then
    if("$argv[6]" == "-np") then
        echo "Usage: movie_generate  filebase outputmode width height"
        echo "                       meshtvx [gui_pid] [-np # | -launch command]"
        echo ""
        echo "When the -np argument is provided, you must also supply the "
        echo "number of processors to use."
        exit
    else if("$argv[6]" == "-launch") then
        echo "Usage: movie_generate  filebase outputmode width height"
        echo "                       meshtvx [gui_pid] [-np # | -launch command]"
        echo ""
        echo "When the -launch argument is provided, you must also supply the "
        echo "command used to launch meshtvx in parallel."
        exit
    else
        # Store the gui's pid.
        set gui_pid = "$argv[6]"

        # Set the ps command based on if it prints command line arguments of
        # the processes it lists.
        if($ps_prints_args == 1) then
            set PS_COMMAND = "ps $gui_pid"
        else
            set PS_COMMAND = "ps"
        endif

        # Make sure that the gui_pid shows up in the process list. 
        # If the pid does not show up in the process list then do not
        # try to signal the gui.
        set found_pid = `$PS_COMMAND | fgrep "$gui_pid"| awk '{printf "%d", $1}'`
        if("$gui_pid" == "$found_pid") then
            set called_from_gui = 1 
        else
            set called_from_gui = 0
        endif  
    endif
endif

if ($#argv == 7) then
    if("$argv[6]" != "-np" && "$argv[6]" != "-launch") then
        echo "Usage: movie_generate  filebase outputmode width height"
        echo "                       meshtvx [gui_pid] [-np # | -launch command]"
        exit
    endif

    if("$argv[6]" == "-np") then
        # Store the number of processors in a variable.
        set np_count = `echo "$argv[7]" | awk '{printf "%d", (($1>0)?$1:0)}'`
        if(np_count == 0) then
            echo "The number of processors must be an integer greater than zero."
            exit
        endif
    else
        # Store the command used to launch meshtvx
        set launch_command = "$argv[7]"
        set launch_command_given = 1
    endif

    # make meshtvx run in parallel
    set running_parallel = 1
endif

if ($#argv == 8) then
    if("$argv[7]" != "-np" && "$argv[7]" != "-launch") then
        echo "Usage: movie_generate  filebase outputmode width height"
        echo "                       meshtvx [gui_pid] [-np # | -launch command]"
        echo ""
        echo "When the -np argument is provided, you must also supply the "
        echo "number of processors to use."
        exit
    endif

    if("$argv[7]" == "-np") then
        # Store the number of processors in a variable.
        set np_count = `echo "$argv[8]" | awk '{printf "%d", (($1>0)?$1:0)}'`
        if(np_count == 0) then
            echo "The number of processors must be an integer greater than zero."
            exit
        endif
    else
        # Store the command used to launch meshtvx
        set launch_command = "$argv[8]"
        set launch_command_given = 1
    endif

    # make meshtvx run in parallel
    set running_parallel = 1
    # Store the GUI's pid.
    set gui_pid = "$argv[6]"

    # Set the ps command based on if it prints command line arguments of
    # the processes it lists.
    if($ps_prints_args == 1) then
        set PS_COMMAND = "ps $gui_pid"
    else
        set PS_COMMAND = "ps"
    endif

    # Make sure that the gui_pid shows up in the process list. 
    # If the pid does not show up in the process list then do not
    # try to signal the gui.
    set found_pid = `$PS_COMMAND | fgrep "$gui_pid"| awk '{printf "%d", $1}'`
    if("$gui_pid" == "$found_pid") then
        set called_from_gui = 1 
    else
        set called_from_gui = 0
    endif  
endif

# Since the user is allowed to specify meshtvx's path and name in the
# command line to this script, make sure that the name the user gives
# exists.  But first, check to see if just "meshtvx" has been
# provided, since that is what the GUI will give.
set TMP = "meshtvx"
if( $MESHTVX == $TMP ) then
    # There is no path to the executable, which means either that the
    # the GUI has provided it (in which case we want to use whichever
    # meshtvx comes first in the user's path) or the user has provided
    # it (in which case, we'll still use the first in the user's path
    # and if that's the wrong one, he'll have to run it with
    # ./meshtvx.
    set MESHTVX  = `which -f meshtvx`
endif

# At this point, we now have meshtvx with a path before it, or
# something odd.  So let's make sure that the executable exists.
if(! -e $MESHTVX) then
    if($called_from_gui == 1) then
        #Signal the gui that the script is done.
        kill -USR1 $gui_pid
    else
        echo "$MESHTVX does not exist.\n"
    endif
    exit
endif

# add on to the meshtvx name if parallel 
if($running_parallel == 1) then
    if ($launch_command_given == 1) then
        set MESHTVX = "$launch_command $MESHTVX"
    else
        set MESHTVX = "mpirun -np $np_count "$MESHTVX
    endif
endif 

# Check to see if the MESHTVHOME environment variable is set. We just need
# to do this on IRIX systems when we're doing mpeg because of mpeg_encode.
if($OS_NAME == "IRIX" && ($outputmode != "rgb") && ($outputmode != "tiff")) then
    if($MESHTVHOME == "") then
        # Signal the gui that no files were created.
        if($called_from_gui == 1) then
            kill -USR1 $gui_pid
        else
            echo "Before using movie_generate, you must first set the MESHTVHOME "
            echo "environment variable. Please email MeshTV@viper.llnl.gov for "
            echo "assistance."
        endif
        exit
    else
        # MESHTVHOME is set, but check to see if the mpeg_encode program
        # is present.
        if(! -e $MPEGCONV) then
            # Signal the gui that no files were created.
            if($called_from_gui == 1) then
                kill -USR1 $gui_pid
            else
                echo "The movie_generate script cannot find mpeg_encode at $MPEGCONV."
                echo "Make sure the MESHTVHOME environment variable is set properly. "
                echo "Please email MeshTV@viper.llnl.gov for assistance."
            endif
            exit
        endif
    endif
endif

# Check to see if there are already files with the same filebase. If there
# are, then create a new directory and move all of the affected files to the 
# new directory.
#
set frame_zero_rgb  = `echo $filebase | awk '{printf "%s0000.rgb",$1}'`
set frame_zero_tiff = `echo $filebase | awk '{printf "%s0000.tif",$1}'`
set frame_zero_ppm  = `echo $filebase | awk '{printf "%s0000.ppm",$1}'`
if((-e $frame_zero_rgb) || (-e $frame_zero_tiff) || (-e $frame_zero_ppm) || (-e $filebase.mpeg)) then
    @ dir_no = 0    
    set dir_name = `echo $filebase $dir_no | awk '{printf "%s_dir%d",$1,$2}'`  
    while( -e $dir_name)
        @ dir_no++
        set dir_name = `echo $filebase $dir_no | awk '{printf "%s_dir%d",$1,$2}'`
    end
    # At this point, the name contained in $dir_name should not 
    # exist. Use dir_name to create a directory. Then move all 
    # the affected files to that directory.
    mkdir $dir_name

    if(-e $frame_zero_ppm) then
        mv $filebase*.ppm $dir_name
    endif
    if(-e $frame_zero_rgb) then
        mv $filebase*.rgb $dir_name
    endif
    if(-e $frame_zero_tiff) then
        mv $filebase*.tif $dir_name
    endif

    # Look for an mpeg that shares the name too. Move if found.
    if(-e $filebase.mpeg) then 
        mv $filebase.mpeg $dir_name
    endif
endif

#
# Start meshtvx using the parameter file that was generated by clicking the
# Save movie->Apply button. This creates the source rgb images for the mpeg
# converter program.  TIFF files are created here if requested. 
#
set meshtvx_param_file = $filebase.meshtvx.params

if ( $outputmode == "rgb" ) then
  $MESHTVX -nowin -xres $width -yres $height -s $meshtvx_param_file -rgb $filebase >/dev/null
else if ( $outputmode == "tiff" ) then
  $MESHTVX -nowin -xres $width -yres $height -s $meshtvx_param_file -tif $filebase >/dev/null
else
  # The mpeg generator will be called, make sure to generate ppm files.
  $MESHTVX -nowin -xres $width -yres $height -s $meshtvx_param_file -ppm $filebase >/dev/null
endif

# At this point, the gui that launched this script might not exist
# anymore, see if it does exist. If so, then send signals to it.
#
if($called_from_gui == 1) then
    # Set the ps command based on if it prints command line arguments of
    # the processes it lists.
    if($ps_prints_args == 1) then
        set PS_COMMAND = "ps $gui_pid"
    else
        set PS_COMMAND = "ps"
    endif

    set found_pid = `$PS_COMMAND | fgrep "$gui_pid"| awk '{printf "%d", $1}'`
    if("$gui_pid" == "$found_pid") then
        set called_from_gui = 1 
    else
        set called_from_gui = 0
    endif  
endif

# Handle RGB files.
if ( $outputmode == "rgb" ) then
    if(-e $frame_zero_rgb) then
        if ( $called_from_gui == 1) then     
            # If the first file was created, tell the gui that 
            # files were created.
            #
            kill -USR2 $gui_pid        
                   
            # Notify the gui that the script is done. Trying a sleep
            # to delay the signal in hopes that they'll arrive in the 
            # proper order.
            #
            sleep 2
            kill -USR1 $gui_pid
        else
            echo "RGB files have been created.\n"
        endif        
    else
        if( $called_from_gui == 1) then
            kill -USR1 $gui_pid
        else
            echo "RGB files could not be created.\n"
        endif
    endif
    rm $filebase.meshtvx.params
    exit
endif

# Handle TIFF files.
if ( $outputmode == "tiff" ) then
    if(-e $frame_zero_tiff) then
        if ( $called_from_gui == 1) then     
            # If the first file was created, tell the gui that 
            # files were created.
            #
            kill -USR2 $gui_pid        
                   
            # Notify the gui that the script is done. Trying a sleep
            # to delay the signal in hopes that they'll arrive in the 
            # proper order.
            #
            sleep 2
            kill -USR1 $gui_pid
        else
            echo "TIFF files have been created.\n"
        endif        
    else
        if( $called_from_gui == 1) then
            kill -USR1 $gui_pid
        else
            echo "TIFF files could not be created.\n"
        endif
    endif
    rm $filebase.meshtvx.params
    exit
endif

# If the first frame ppm file is found, then it means that meshtvx was
# at least partially successful, so call the mpeg encoder if in Irix.
# Otherwise, do nothing and no mpeg movie will be generated.
if($OS_NAME == "IRIX") then
    if(-e $frame_zero_ppm) then
        $MPEGCONV $filebase.mpeg.params > /dev/null
    endif
else
    echo "The MPEG encoder is only supported on IRIX machines.\n"
endif

# At this point, the gui that launched this script might not exist
# anymore, see if it does exist. If so, then send signals to it.
#
if($called_from_gui == 1) then 
    set found_pid = `$PS_COMMAND | fgrep "$gui_pid"| awk '{printf "%d", $1}'`
    if("$gui_pid" == "$found_pid") then
        set called_from_gui = 1 
    else
        set called_from_gui = 0
    endif  
endif

# If the mpeg was created, then remove the intermediate files.
if (-e $filebase.mpeg ) then
   if ( $called_from_gui == 1) then
      #
      # Notify the gui that the script was successful   
      #
      kill -USR2 $gui_pid
      #
      # Notify the gui that the script is done. Trying a sleep
      # to delay the signal in hopes that they'll arrive in the 
      # proper order.
      #
      sleep 2
      kill -USR1 $gui_pid    
   else
      echo "MPEG converter finished. Output file is $filebase.mpeg\n"
   endif 
   #
   # Now do a little cleanup of the graphics and param files that were 
   # generated. It's ok to do this since if the user wanted RGB files, 
   # the script would have bailed before this point.
   #
   rm $filebase*.ppm
   rm $filebase.mpeg.params
   rm $filebase.meshtvx.params
else
   if ( $called_from_gui == 1) then      
      #
      # Notify the gui that the script is done.
      #
      kill -USR1 $gui_pid             
   else
      echo "MPEG converter failed. $filebase.mpeg could not be created.\n"
   endif 
endif

