#! /bin/csh -f
# Last edited on 2006-11-24 01:56:14 by stolfi

set usage = "$0 [ -fast | -fair | -good | -quick ] [ -detail XMIN XMAX YMIN YMAX ] [ -segment XSEG/NX YSEG/NY ] [ -tiny | -small | -plain | -big | -size WD HT ] [ -scale s ] [ -in DIR [ -norender ] ] [ -list DIRLIST ] [ -hist ] [ -transparent | -blackbg | -whitebg ] [ -show|-noshow ] [ -noindex ] [ -preview ] NAME.pov"

# Generates POVRAY rendering of a scene (GIF output)
# 
# By default, all output (incluring a copy of all scene sources) goes
# to a subdirectory whose name is the current date and time. The
# subdirectory is automatically deleted if the run fails. Otherwise
# the subdirectory's name is stored in the files ".last" in the
# current directory, and appended to the file DIRLIST (which defaults
# to "NAME.dirlist"). Also a symbolic link ".lastdir" is made to point
# to it.
#
# The current directory may include a file called NAME.sizes
# redefining the csh variables
#   ${tinysize}   default ( 050 050 )
#   ${smallsize}  default ( 100 100 )
#   ${plainsize}  default ( 200 200 )
#   ${bigsize}    default ( 400 400 )
# 
# The current directory may also include files called NAME.options
# and povray.options, with additional options to be passed to POVRAY
# (for instance, "+L" options).
#
# The "-transparent" flag runs povray twice, with black and white
# background, and then uses ppmoquant to merge them into 
# a partially-transparent gif.  The "-blackbg" and "-whitebg"
# options create only one of the two images, and will not 
# run ppmoquant.  In either case, the NAME.pov file should #include 
# the file "background.inc", generated by this script,
# which will contain
#    #declare bgColor = color rgb <...>
#    background {color bgColor}
#
# The "-in" flag specifies that povray should be run in an
# existing directory DIR, which should contain all the 
# necessary files.  In this case, DIR is not removed if the run fails.
# This option is useful to re-run an old run with, say, increased 
# resolution or improved tools.
#
# The "-norender" option can be used in conjuntion with "-in"
# to force the re-conversion of existing ".ppm" files to ".gif".
#
# The "-preview" option displays a coarse preview of the image 
# while rendering.
# 
# The option "-segment XSEG/NX YSEG/NY" adds declarations 
#   segment_h = XSEG   segment_h_num = NX
#   segment_v = YSEG   segment_h_num = NY
# to the background.inc file.
#

set povbin = "${STOLFIHOME}/pkg/povray-3.50c-1/PUB/${PLATFORM}/bin"
set postertools = "${STOLFIHOME}/posters/tools"
set povray = ${povbin}/x-povray
set gnice = ( "nice" "-n" "19" )
set gifview = ( "display" )

set path = ( ${postertools} ${povbin} ${path} )

set cmdname = "$0"
set runargs = "$*"
echo "${cmdname} ${runargs}"

set size = ( "plain" )
set rays = 3
set qual = 9
set transp = 0
set scaleopts = ( )
set viewopts = ( )
set show = 1
set render = 1
set makeindex = 1
unset givendir 
unset dirlist
set detailopts = ( )
set histopts = ( "+HTX" )
set segments = ( )

while ( ( $#argv > 0 ) && ( "x$1" =~ x-* ) )
  if ( "x$1" == "x-quick" ) then 
    set rays = 1
    set qual = 4
    shift
  else if ( "x$1" == "x-show" ) then 
    set show = 1
    shift
  else if ( "x$1" == "x-noshow" ) then 
    set show = 0
    shift
  else if ( "x$1" == "x-noindex" ) then 
    set makeindex = 0
    shift
  else if ( "x$1" == "x-norender" ) then 
    set render = 0
    shift
  else if ( "x$1" == "x-hist" ) then 
    set histopts = ( "+HTP" )
    shift
  else if ( "x$1" == "x-preview" ) then 
    set viewopts = ( "+D" "+SP32" "+EP4" )
    shift
  else if ( ( $#argv >= 5 ) && ( "x$1" == "x-detail" ) ) then 
    set detailopts = (  "+SC$2" "+EC$3" "+SR$4" "+ER$5" )
    shift; shift; shift; shift; shift
  else if ( ( $#argv >= 3 ) && ( "x$1" == "x-segment" ) ) then 
    set segments = ( $2 $3 )
    shift; shift; shift
  else if ( "x$1" == "x-fast" ) then 
    set rays = 1
    set qual = 9
    shift
  else if ( "x$1" == "x-fair" ) then 
    set rays = 2
    set qual = 9
    shift
  else if ( "x$1" == "x-good" ) then 
    set rays = 4
    set qual = 9
    shift
  else if ( "x$1" == "x-tiny" ) then 
    set size = ( "tiny" )
    shift
  else if ( "x$1" == "x-small" ) then 
    set size = ( "small" )
    shift
  else if ( "x$1" == "x-plain" ) then 
    set size = ( "plain" )
    shift
  else if ( "x$1" == "x-big" ) then 
    set size = ( "big" )
    shift
  else if ( ( $#argv >= 3 ) && ( "x$1" == "x-size" ) ) then 
    set size = ( $2 $3 )
    shift; shift; shift
  else if ( ( $#argv >= 2 ) && ( "x$1" == "x-scale" ) ) then 
    set scaleopts = ( "-scale" "$2" );  shift; shift;
  else if ( "x$1" == "x-transparent" ) then 
    set transp = 1;  set bgrounds = ( 0 1 );  shift
  else if ( "x$1" == "x-blackbg" ) then 
    set transp = 1;  set bgrounds = ( 0 ); shift
  else if ( "x$1" == "x-whitebg" ) then 
    set transp = 1;  set bgrounds = ( 1 ); shift
  else if ( ( $#argv >= 3 ) && ( "x$1" == "x-in" ) ) then 
    set givendir = "$2";  shift; shift
  else if ( ( $#argv >= 3 ) && ( "x$1" == "x-list" ) ) then 
    set dirlist = "$2";  shift; shift
  else
    echo 'bad option "'"$1"'"'
    echo "usage: ${usage}" ; exit 1
  endif
end

if ( ( ! ${render} ) && ( ! $?givendir ) ) then
  echo 'option "-norender" can be used only with "-in DIR"'
  echo "usage: ${usage}"; exit 1
endif

if ( $#argv != 1 ) then
  echo "usage: ${usage}"; exit 1
endif
 
set name = "$1"
if ( "x${name:e}" != "xpov" ) then
  echo "usage: ${usage}"; exit 1
endif
set name = ${name:r}

if ( ! ( $?dirlist ) ) set dirlist = "${name}.dirlist"

if ( $?givendir ) then
  if ( ! ( -d ${givendir} ) ) then
    echo "$givendir: not a directory" ; exit 1
  endif
  set d = "${givendir}"
  echo "re-generating picture in directory $d"
  if ( ${render} ) then
    if ( -r $d/run-povray.args ) /bin/mv $d/run-povray.args $d/run-povray.args~
    echo "on `date +%Y-%m-%d-%H%M%S`:" >> $d/${name}.comments
    if ( -r ${name}.comments ) cat ${name}.comments >> $d/${name}.comments
  endif
else
  set d = `date +%Y-%m-%d-%H%M%S`
  echo "generating picture in directory $d"
  mkdir $d
  cp -a $0 $d
  cp -a ${name}.pov $d
  cp -a [a-zA-Z0-9]*.{inc,incx,gif,png,csh,make,awk} $d
  foreach f ( ${name}.{sizes,options,comments} povray.options do-run-povray )
    if ( -r $f ) cp -p $f $d
  end
endif

set curd = "$cwd"
cd $d

if ( $#size == 1 ) then
  if ( -r ${name}.sizes ) then
    source ${name}.sizes 
  endif
  if ( ! $?tinysize )  set tinysize  = ( 050 050 )
  if ( ! $?smallsize ) set smallsize = ( 100 100 )
  if ( ! $?plainsize ) set plainsize = ( 200 200 )
  if ( ! $?bigsize )   set bigsize   = ( 400 400 )
  if ( "$size[1]" == "tiny" ) then
    set size = ( ${tinysize} )
  else if ( "$size[1]" == "small" ) then
    set size = ( ${smallsize} )
  else if ( "$size[1]" == "plain" ) then
    set size = ( ${plainsize} )
  else if ( "$size[1]" == "big" ) then
    set size = ( ${bigsize} )
  else 
    echo "run-povray: internal bug (size = ${size})"
    exit 1
  endif
endif

if ( -r ${name}.options ) then
  set nameopts = ( `cat ${name}.options` )
else
  set nameopts = ( )
endif
if ( -r povray.options ) then
  set povopts = ( `cat povray.options` )
else
  set povopts = ( )
endif

if ( ${render} ) then
  echo "${cmdname} ${runargs}" > run-povray.args
  echo "[`uname -n`] ${cmdname:t} ${runargs}" >> ${name}.comments

  if ( -r ${name}.make ) then
    ${gnice} \
      make -f ${name}.make all \
        |& tee ${name}.make.log
  endif
endif

/bin/rm -f ${name}.gif p.gif
set povrayok = 1

/bin/rm -f background.inc

if ( $#segments > 0 ) then
  echo "#declare segment_h     = ${segments[1]:h};" >> background.inc
  echo "#declare segment_h_num = ${segments[1]:t};" >> background.inc
  echo "#declare segment_v     = ${segments[2]:h};" >> background.inc
  echo "#declare segment_v_num = ${segments[2]:t};" >> background.inc
endif

if ( ${transp} == 0 ) then
  if ( ${render} ) then
    # run povray once, with gray background:
    echo "#declare bgColor = color rgb <0.5,0.5,0.5>;" >> background.inc
    echo "#declare bg_color = bgColor;" >> background.inc
    echo "background { color bg_color }" >> background.inc
    ${gnice} \
      ${povray} \
        +FP +Q${qual} +R${rays} +W${size[1]} +H${size[2]} \
        +A0.0 +AM1 \
        +MB1 \
        ${histopts} +HN${name}-time.ppm \
        ${viewopts} ${povopts} ${nameopts} ${detailopts} \
        +L${STOLFIHOME}/PUB/povray +L.. \
        +GI${name}-restart.ini \
        +I${name}.pov \
        +O${name}.ppm \
      |& tee povray.log

    if ( ( ! ( -r ${name}.ppm ) ) || ( -z ${name}.ppm ) ) then
      set povrayok = 0
    endif
  endif

  if ( ${povrayok} ) then
    ln -s ${name}.ppm p.ppm
    ln -s ${name}.comments p.comments

    linear-ppm-to-gif ${scaleopts} ${name}.ppm > ${name}.gif
    ln -s ${name}.gif p.gif

    linear-ppm-to-gif -ysize 50 ${name}.ppm > ${name}-icon.gif
    ln -s ${name}-icon.gif p-icon.gif
  endif
else
  if ( ${render} ) then
    # run povray twice, with black and white backgrounds:
    foreach bg ( ${bgrounds} )
      echo "=== generating image with background = ${bg} ==="
      echo "#declare bgColor = color rgb <${bg}, ${bg}, ${bg}>;" >> background.inc
      echo "background { color bgColor }" >> background.inc
      ${gnice} \
        ${povray} \
          +FP +Q${qual} +R${rays} +W${size[1]} +H${size[2]} \
          +A0.0 +AM1 \
          +MB1 \
          ${viewopts} ${povopts} ${nameopts} ${detailopts} \
          +L${STOLFIHOME}/PUB/povray \
          +GI${name}-restart.ini \
          +I${name}.pov \
          +O${name}-${bg}.ppm \
        |& tee povray-${bg}.log
      if ( ( ! ( -r ${name}-${bg}.ppm ) ) || ( -z ${name}-${bg}.ppm ) ) then
        set povrayok = 0
        break
      else
        ln -s ${name}-${bg}.ppm p-${bg}.ppm
      endif
    end
  endif

  if ( ${povrayok} && ( -r ${name}-0.ppm ) && ( -r ${name}-1.ppm ) ) then

    linear-ppm-pair-to-gif ${scaleopts} ${name}-{0,1}.ppm > ${name}.gif
    ln -s ${name}.gif p.gif
    ln -s ${name}.comments p.comments

    linear-ppm-pair-to-gif -ysize 50 ${name}-{0,1}.ppm > ${name}-icon.gif
    ln -s ${name}-icon.gif p-icon.gif

  endif
endif

if ( ${render} ) then
  if ( -r ${name}.make ) then
    make -f ${name}.make clean
  endif
endif

cd ${curd}
if ( ( -r $d/${name}.gif ) && ( ! ( -z $d/${name}.gif ) ) ) then
  echo 'rendering succeeded in directory '"$d"
  echo "$d" > .last
  rm -f .lastdir; ln -s "$d" .lastdir
  echo "$d" >> ${dirlist}
  if ( ${show} != 0 ) ${gifview} $d/p.gif $d/${name}*.{gif,ppm} $d/p.comments &
  make-image-index-entry $d/${name}.gif > $d/${name}.html-inc
  ln -s ${name}.html-inc $d/p.html-inc   
  if ( $makeindex) then
    ${postertools}/make-povray-index
  endif
  exit 0
else
  echo 'rendering failed in directory '"$d"
  if ( ( ! $?givendir ) && ( ! ${povrayok} ) ) then
    echo "deleting directory $d"
    /bin/rm -rf "$d"
  endif
  exit 1
endif
