#! /bin/bash # Last edited on 2011-02-06 23:15:03 by stolfilocal 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 ] [ -show|-noshow ] [ -noindex ] [ -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"). 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 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. # # By default, the script rebulds the picture index in the # current directory ("index.html"). Use "-noindex" to supress it. # ###################################################################### #### Commands executed in the scene directory ######################## # # Clear the ".last" file (name of last render directory): echo "NONE" > .last povbin="/usr/local/bin" postertools="${STOLFIHOME}/posters/tools" povray=${povbin}/povray path=( ${postertools} ${povbin} ${path} ) cmdname="$0" runargs="$@" echo "${cmdname} ${runargs}" 1>&2 size=( "plain" ) rays=3 qual=9 transp=0 scaleopts=( ) viewopts=( ) show=0 # show=1 render=1 makeindex=1 givendir= dirlist= detailopts=( ) # histopts=( "+HTX" ) histopts=( ) quantopts=( ) segments=( ) bgrounds=( 1 ) while [[ ( $# -gt 0 ) && ( "/${1:0:1}" == "/-" ) ]]; do if [[ "/$1" == "/-show" ]]; then show=1; shift elif [[ "/$1" == "/-noshow" ]]; then show=0; shift elif [[ "/$1" == "/-noindex" ]]; then makeindex=0; shift elif [[ "/$1" == "/-norender" ]]; then render=0; shift elif [[ "/$1" == "/-hist" ]]; then histopts=( "+HTP" ); shift elif [[ "/$1" == "/-preview" ]]; then viewopts=( "+D" "+SP32" "+EP4" ); shift elif [[ ( $# -ge 5 ) && ( "/$1" == "/-detail" ) ]]; then detailopts=( "+SC$2" "+EC$3" "+SR$4" "+ER$5" ); shift; shift; shift; shift; shift elif [[ ( $# -ge 3 ) && ( "/$1" == "/-segment" ) ]]; then segments=( $2 $3 ); shift; shift; shift elif [[ "/$1" == "/-quick" ]]; then rays=1; qual=4; shift elif [[ "/$1" == "/-fast" ]]; then rays=1; qual=9; shift elif [[ "/$1" == "/-fair" ]]; then rays=2; qual=9; shift elif [[ "/$1" == "/-good" ]]; then rays=4; qual=9; shift elif [[ "/$1" == "/-tiny" ]]; then size=( "tiny" ); shift elif [[ "/$1" == "/-small" ]]; then size=( "small" ); shift elif [[ "/$1" == "/-plain" ]]; then size=( "plain" ); shift elif [[ "/$1" == "/-big" ]]; then size=( "big" ); shift elif [[ ( $# -ge 3 ) && ( "/$1" == "/-size" ) ]]; then size=( $2 $3 ); shift; shift; shift elif [[ ( $# -ge 2 ) && ( "/$1" == "/-qmethod" ) ]]; then quantopts=( "-qmethod" "$2" ); shift; shift elif [[ ( $# -ge 2 ) && ( "/$1" == "/-scale" ) ]]; then scaleopts=( "-scale" "$2" ); shift; shift; elif [[ "/$1" == "/-transparent" ]]; then transp=1; bgrounds=( 0 1 ); shift elif [[ "/$1" == "/-blackbg" ]]; then transp=1; bgrounds=( 0 ); shift elif [[ "/$1" == "/-whitebg" ]]; then transp=1; bgrounds=( 1 ); shift elif [[ ( $# -ge 3 ) && ( "/$1" == "/-in" ) ]]; then givendir="$2"; shift; shift elif [[ ( $# -ge 3 ) && ( "/$1" == "/-list" ) ]]; then dirlist="$2"; shift; shift else echo 'bad option "'"$1"'"' 1>&2 echo "usage: ${usage}" 1>&2; exit 1 fi done if [[ ( ${render} -eq 0 ) && ( "/${givendir}" == "/" ) ]]; then echo 'option "-norender" can be used only with "-in DIR"' 1>&2 echo "usage: ${usage}" 1>&2; exit 1 fi if [[ $# -ne 1 ]]; then echo "usage: ${usage}" 1>&2; exit 1 fi name="$1" if [[ "/${name##*.}" != "/pov" ]]; then echo "usage: ${usage}" 1>&2; exit 1 fi name=${name%.*} if [[ ! ( "/${dirlist}" != "/" ) ]]; then dirlist="${name}.dirlist" fi if [[ "/${givendir}" != "/" ]]; then if [[ ! ( -d ${givendir} ) ]]; then echo "${givendir}: not a directory" 1>&2; exit 1 fi d="${givendir}" echo "re-generating picture in directory ${d}" 1>&2 if [[ ${render} -ne 0 ]]; then if [[ -r ${d}/run-povray.args ]]; then /bin/mv ${d}/run-povray.args ${d}/run-povray.args~ fi echo "on `date +%Y-%m-%d-%H%M%S`:" >> ${d}/${name}.comments if [[ -r ${name}.comments ]]; then cat ${name}.comments >> ${d}/${name}.comments fi fi else d=`date +%Y-%m-%d-%H%M%S` echo "generating picture in directory ${d}" 1>&2 mkdir ${d} cp -a ${name}.pov ${d} shopt -sq nullglob cp -a $0 [a-zA-Z0-9]*.{inc,incx,gif,png,csh,sh,make,awk} ${d} shopt -uq nullglob for f in ${name}.{sizes,options,comments} povray.options do-run-povray ; do if [[ -r ${f} ]]; then cp -p ${f} ${d} fi done fi # ###################################################################### curd="${PWD}" cd ${d} pwd #### Commands executed in the run sub-directory ###################### # if [[ ${#size[@]} -eq 1 ]]; then if [[ -s ${name}.sizes ]]; then # The file ${name}.sizes ought to define "${tinysize}" "${smallsize}" "${plainsize}" "${bigsize}". # Convert old "csh" format to "bash" format if necessary: cat ${name}.sizes \ | sed \ -e 's:^set *::g' \ -e 's: *= *:=:g' \ -e 's:\( [0-9][0-9]*\): "\1":g' \ > .sizes source .sizes fi if [[ "/${tinysize[@]}" == "/" ]]; then tinysize=( ); fi if [[ "/${smallsize[@]}" == "/" ]]; then smallsize=( ); fi if [[ "/${plainsize[@]}" == "/" ]]; then plainsize=( ); fi if [[ "/${bigsize[@]}" == "/" ]]; then bigsize=( ); fi if [[ "${size[0]}" == "tiny" ]]; then size=( ${tinysize[@]} ) elif [[ "${size[0]}" == "small" ]]; then size=( ${smallsize[@]} ) elif [[ "${size[0]}" == "plain" ]]; then size=( ${plainsize[@]} ) elif [[ "${size[0]}" == "big" ]]; then size=( ${bigsize[@]} ) else echo "run-povray: internal bug (size = ${size[@]})" 1>&2 exit 1 fi fi if [[ -r ${name}.options ]]; then nameopts=( `cat ${name}.options` ) else nameopts=( ) fi if [[ -r povray.options ]]; then povopts=( `cat povray.options` ) else povopts=( ) fi if [[ ${render} -ne 0 ]]; then echo "${cmdname} ${runargs}" > run-povray.args echo "[`uname -n`] ${cmdname##*/} ${runargs}" >> ${name}.comments if [[ -r ${name}.make ]]; then make -f ${name}.make all \ 2>&1 | tee ${name}.make.log fi fi # Remove any old output image files: /bin/rm -f ${name}.{ppm,png} ${name}-{0,1}.{ppm,png} ${name}-icon.png # Remove any old symbolic links: /bin/rm -f p.{ppm,png} p-{0,1}.{ppm,png} p-icon.png p.comments # Termination status of povray command: povrayok=1 # Create background/segment file: /bin/rm -f background.inc if [[ ${#segments[@]} -gt 0 ]]; then echo "#declare segment_h = ${segments[0]%%/*};" >> background.inc echo "#declare segment_h_num = ${segments[0]##*/};" >> background.inc echo "#declare segment_v = ${segments[1]%%/*};" >> background.inc echo "#declare segment_v_num = ${segments[1]##*/};" >> background.inc fi if [[ ${transp} -eq 0 ]]; then if [[ ${render} -ne 0 ]]; then # run povray once, with gray background: echo "=== generating png image ===" 1>&2 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 ${povray} \ +FN +Q${qual} +R${rays} +W"${size[0]}" +H"${size[1]}" \ +A0.0 +AM1 \ +MB1 \ ${histopts[@]} +HN${name}-time.ppm \ ${viewopts[@]} ${povopts[@]} ${nameopts[@]} ${detailopts[@]} \ +L${STOLFIHOME}/PUB/povray +L.. \ +GI${name}-restart.ini \ -GS -GR \ +I${name}.pov \ +O${name}.png \ 2>&1 \ | tee povray.log \ | ${postertools}/reformat-povray-output if [[ ! ( -s ${name}.png ) ]]; then povrayok=0 fi fi if [[ ${povrayok} -ne 0 ]]; then convert ${name}.png -resize 'x50' ${name}-icon.png ln -s ${name}.png p.png ln -s ${name}.comments p.comments ln -s ${name}-icon.png p-icon.png fi else if [[ ${render} -ne 0 ]]; then # run povray twice, with black and white backgrounds: for bg in ${bgrounds[@]} ; do echo "=== generating ppm image with background = ${bg} ===" 1>&2 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[0]}" +H"${size[1]}" \ +AM1 +A0.0 \ +MB1 \ ${viewopts[@]} ${povopts[@]} ${nameopts[@]} ${detailopts[@]} \ +L${STOLFIHOME}/PUB/povray +L.. \ +GI${name}-restart.ini \ -GS -GR \ +I${name}.pov \ +O${name}-${bg}.ppm \ 2>&1 \ | tee povray-${bg}.log \ | ${postertools}/reformat-povray-output if [[ ! ( -s ${name}-${bg}.ppm ) ]]; then povrayok=0 break else ln -s ${name}-${bg}.ppm p-${bg}.ppm fi done fi if [[ ( ${povrayok} -ne 0 ) && ( -s ${name}-0.ppm ) && ( -s ${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 fi fi if [[ ${render} -ne 0 ]]; then if [[ -s ${name}.make ]]; then make -f ${name}.make clean fi fi # ###################################################################### cd ${curd} pwd #### Commands executed in the scene directory ######################## # if [[ -s ${d}/${name}.png ]]; then echo 'rendering succeeded in directory '"${d}" 1>&2 echo "${d}" > .last rm -f .lastdir; ln -s "${d}" .lastdir echo "${d}" >> ${dirlist} /bin/rm -f ${d}/${name}.html-inc ${d}/p.html-inc make-image-index-entry ${d}/${name}.png > ${d}/${name}.html-inc ln -s ${name}.html-inc ${d}/p.html-inc if [[ ${makeindex} -ne 0 ]]; then ${postertools}/make-povray-index fi if [[ ${show} -ne 0 ]]; then display -title '%d' ${d}/p.png ${d}/${name}*.{png,ppm} ${d}/p.comments fi exit 0 else echo 'rendering failed in directory '"${d}" 1>&2 if [[ ( "/${givendir}" == "/" ) && ( ${povrayok} -eq 0 ) ]]; then echo "deleting directory ${d}" 1>&2 /bin/rm -rf "${d}" fi exit 1 fi