#! /bin/csh -f
# Last edited on 2003-09-15 02:17:50 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 ] [ -qmethod {fs|near|noquant} ] [ -transparent | -blackbg | -whitebg ] [ -noshow ] [ -preview ] NAME.pov"

# Generates POVRAY rendering of a scene (PNG 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")
# 
# 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 combines them into an RGBA
# (partially-transparent) png. The "-blackbg" and "-whitebg" options
# create only one of the two images, and will not create the
# semi-transparent version. 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 ".png".
# 
# 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.
# 
# If "-qmethod" is anything other than "noquant" (the default),
# then the resulting image will be color-reduced with ppmvquant 
# or ppmoquant.
# 
 
#### in the scene directory ########################################
# 

# set povbin = "/n/lac/pkg/povray-3.01-1/PUB/${PLATFORM}/bin"
set povbin = "/home/staff/stolfi/programs/c/povray-3.50c-1/PUB/${PLATFORM}/bin"
set postertools = "/home/staff/stolfi/posters/tools"
set povray = ${povbin}/povray
if ( -x /n/gnu/bin/nice ) then
  set gnice = ( "/n/gnu/bin/nice" "-n" "19" )
else
  set gnice = ( "/bin/nice" "-n" "19" )
else
  set gnice = ( )
endif
if ( -x /n/image/bin/xv ) then
  set pngview = ( "/n/image/bin/xv" )
else
  set pngview = ( "display" )
endif

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
unset givendir 
unset dirlist
set detailopts = ( )
# set histopts = ( "+HTX" )
set histopts = ( )
set quantopts = ( )
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-noshow" ) then 
    set show = 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-qmethod" ) ) then 
    set quantopts = ( "-qmethod" "$2" );  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 ${name}.pov $d
  cp -a $0 [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

#### in the run sub-directory ########################################
# 

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

# Remove any old output image files:
/bin/rm -f ${name}.ppm ${name}.png ${name}-{0,1}.png ${name}-icon.png

# Remove any old symbolic links:
/bin/rm -f p.ppm p.png p-{0,1}.png p.comments p-icon.png

# Termination status of povray command:
set povrayok = 1

# Create background/segment file:
/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 \
        ${histopts} +HN${name}-time.ppm \
        ${viewopts} ${povopts} ${nameopts} ${detailopts} \
        +L${HOME}/PUB/povray \
        +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-png ${quantopts} ${scaleopts} ${name}.ppm > ${name}.png
    ln -s ${name}.png p.png

    linear-ppm-to-png ${quantopts} -ysize 50 ${name}.ppm > ${name}-icon.png
    ln -s ${name}-icon.png p-icon.png
  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]} \
          +AM1 +A0.0 \
          ${viewopts} ${povopts} ${nameopts} ${detailopts} \
          +L/home/staff/stolfi/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-png ${quantopts} ${scaleopts} ${name}-{0,1}.ppm > ${name}.png
    ln -s ${name}.png p.png
    ln -s ${name}.comments p.comments

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

  endif
endif

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

#
######################################################################

cd ${curd}

#### in the scene directory ########################################
# 

if ( ( -r $d/${name}.png ) && ( ! ( -z $d/${name}.png ) ) ) then
  echo 'rendering succeeded in directory '"$d"
  echo "$d" > .last
  echo "$d" >> ${dirlist}
  /bin/rm -f $d/${name}.html-inc $d/p.html-inc 
  if ( ${show} != 0 ) ${pngview} $d/p.png $d/${name}*.{png,ppm} $d/p.comments &
  make-image-index-entry $d/${name}.png > $d/${name}.html-inc
  ln -s ${name}.html-inc $d/p.html-inc   
  ${postertools}/make-povray-index
  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
