--- ray/src/util/ranimate.c 1996/05/20 11:50:19 2.12
+++ ray/src/util/ranimate.c 2003/02/22 02:07:30 2.29
@@ -1,77 +1,142 @@
-/* Copyright (c) 1996 Regents of the University of California */
-
#ifndef lint
-static char SCCSid[] = "$SunId$ LBL";
+static const char RCSid[] = "$Id: ranimate.c,v 2.29 2003/02/22 02:07:30 greg Exp $";
#endif
-
/*
* Radiance animation control program
+ *
+ * The main difference between this program and ranimove is that
+ * we have many optimizations here for camera motion in static
+ * environments, calling rpict and pinterp on multiple processors,
+ * where ranimove puts its emphasis on object motion, and does
+ * not use any external programs for image generation.
+ *
+ * See the ranimate(1) man page for further details.
*/
+/* ====================================================================
+ * The Radiance Software License, Version 1.0
+ *
+ * Copyright (c) 1990 - 2002 The Regents of the University of California,
+ * through Lawrence Berkeley National Laboratory. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes Radiance software
+ * (http://radsite.lbl.gov/)
+ * developed by the Lawrence Berkeley National Laboratory
+ * (http://www.lbl.gov/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
+ * and "The Regents of the University of California" must
+ * not be used to endorse or promote products derived from this
+ * software without prior written permission. For written
+ * permission, please contact radiance@radsite.lbl.gov.
+ *
+ * 5. Products derived from this software may not be called "Radiance",
+ * nor may "Radiance" appear in their name, without prior written
+ * permission of Lawrence Berkeley National Laboratory.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of Lawrence Berkeley National Laboratory. For more
+ * information on Lawrence Berkeley National Laboratory, please see
+ * .
+ */
+
#include "standard.h"
#include
-#include
#include
#include "view.h"
#include "vars.h"
#include "netproc.h"
+ /* default blur samples */
+#ifndef DEF_NBLUR
+#define DEF_NBLUR 5
+#endif
/* default remote shell */
#ifdef _AUX_SOURCE
#define REMSH "remsh"
#else
#define REMSH "rsh"
#endif
- /* input variables */
-#define HOST 0 /* rendering host machine */
-#define RENDER 1 /* rendering options */
-#define PFILT 2 /* pfilt options */
-#define PINTERP 3 /* pinterp options */
-#define OCTREE 4 /* octree file name */
-#define DIRECTORY 5 /* working (sub)directory */
-#define BASENAME 6 /* output image base name */
-#define VIEWFILE 7 /* animation frame views */
-#define START 8 /* starting frame number */
-#define END 9 /* ending frame number */
-#define RIF 10 /* rad input file */
-#define NEXTANIM 11 /* next animation file */
-#define ANIMATE 12 /* animation command */
-#define TRANSFER 13 /* frame transfer command */
-#define ARCHIVE 14 /* archiving command */
-#define INTERP 15 /* # frames to interpolate */
-#define OVERSAMP 16 /* # times to oversample image */
-#define MBLUR 17 /* samples for motion blur */
-#define RTRACE 18 /* use rtrace with pinterp? */
-#define DISKSPACE 19 /* how much disk space to use */
-#define RESOLUTION 20 /* desired final resolution */
-#define EXPOSURE 21 /* how to compute exposure */
-#define RSH 22 /* remote shell script or program */
+ /* input variables (alphabetical by name) */
+#define ANIMATE 0 /* animation command */
+#define ARCHIVE 1 /* archiving command */
+#define BASENAME 2 /* output image base name */
+#define DIRECTORY 3 /* working (sub)directory */
+#define DISKSPACE 4 /* how much disk space to use */
+#define END 5 /* ending frame number */
+#define EXPOSURE 6 /* how to compute exposure */
+#define HOST 7 /* rendering host machine */
+#define INTERP 8 /* # frames to interpolate */
+#define MBLUR 9 /* motion blur parameters */
+#define NEXTANIM 10 /* next animation file */
+#define OCTREE 11 /* octree file name */
+#define OVERSAMP 12 /* # times to oversample image */
+#define PFILT 13 /* pfilt options */
+#define PINTERP 14 /* pinterp options */
+#define RENDER 15 /* rendering options */
+#define RESOLUTION 16 /* desired final resolution */
+#define RIF 17 /* rad input file */
+#define RSH 18 /* remote shell script or program */
+#define RTRACE 19 /* use rtrace with pinterp? */
+#define START 20 /* starting frame number */
+#define TRANSFER 21 /* frame transfer command */
+#define VIEWFILE 22 /* animation frame views */
int NVARS = 23; /* total number of variables */
VARIABLE vv[] = { /* variable-value pairs */
- {"host", 4, 0, NULL, NULL},
- {"render", 3, 0, NULL, catvalues},
- {"pfilt", 2, 0, NULL, catvalues},
- {"pinterp", 2, 0, NULL, catvalues},
- {"OCTREE", 3, 0, NULL, onevalue},
- {"DIRECTORY", 3, 0, NULL, onevalue},
- {"BASENAME", 3, 0, NULL, onevalue},
- {"VIEWFILE", 2, 0, NULL, onevalue},
- {"START", 2, 0, NULL, intvalue},
- {"END", 2, 0, NULL, intvalue},
- {"RIF", 3, 0, NULL, onevalue},
- {"NEXTANIM", 3, 0, NULL, onevalue},
{"ANIMATE", 2, 0, NULL, onevalue},
- {"TRANSFER", 2, 0, NULL, onevalue},
{"ARCHIVE", 2, 0, NULL, onevalue},
+ {"BASENAME", 3, 0, NULL, onevalue},
+ {"DIRECTORY", 3, 0, NULL, onevalue},
+ {"DISKSPACE", 3, 0, NULL, fltvalue},
+ {"END", 2, 0, NULL, intvalue},
+ {"EXPOSURE", 3, 0, NULL, onevalue},
+ {"host", 4, 0, NULL, NULL},
{"INTERPOLATE", 3, 0, NULL, intvalue},
- {"OVERSAMPLE", 2, 0, NULL, fltvalue},
{"MBLUR", 2, 0, NULL, onevalue},
- {"RTRACE", 2, 0, NULL, boolvalue},
- {"DISKSPACE", 3, 0, NULL, fltvalue},
+ {"NEXTANIM", 3, 0, NULL, onevalue},
+ {"OCTREE", 3, 0, NULL, onevalue},
+ {"OVERSAMPLE", 2, 0, NULL, fltvalue},
+ {"pfilt", 2, 0, NULL, catvalues},
+ {"pinterp", 2, 0, NULL, catvalues},
+ {"render", 3, 0, NULL, catvalues},
{"RESOLUTION", 3, 0, NULL, onevalue},
- {"EXPOSURE", 3, 0, NULL, onevalue},
+ {"RIF", 3, 0, NULL, onevalue},
{"RSH", 3, 0, NULL, onevalue},
+ {"RTRACE", 2, 0, NULL, boolvalue},
+ {"START", 2, 0, NULL, intvalue},
+ {"TRANSFER", 2, 0, NULL, onevalue},
+ {"VIEWFILE", 2, 0, NULL, onevalue},
};
#define SFNAME "STATUS" /* status file name */
@@ -93,7 +158,7 @@ int silent = 0; /* silent mode? */
int noaction = 0; /* take no action? */
char *remsh; /* remote shell program/script */
-char rendopt[2048] = ""; /* rendering options */
+char rendopt[2048]; /* rendering options */
char rresopt[32]; /* rendering resolution options */
char fresopt[32]; /* filter resolution options */
int pfiltalways; /* always use pfilt? */
@@ -108,17 +173,17 @@ struct pslot {
} *pslot; /* process slots */
int npslots; /* number of process slots */
-int lastpid; /* ID of last completed background process */
-PSERVER *lastpserver; /* last process server used */
-
#define phostname(ps) ((ps)->hostname[0] ? (ps)->hostname : astat.host)
struct pslot *findpslot();
+PSERVER *lastpserver; /* last process server with error */
+
VIEW *getview();
-char *getexp();
+char *getexp(), *dirfile();
+int getblur();
-extern time_t fdate(), time();
+extern time_t time();
main(argc, argv)
@@ -151,6 +216,8 @@ char *argv[];
cfname = argv[i];
/* load variables */
loadvars(cfname);
+ /* check variables */
+ checkvalues();
/* did we get DIRECTORY? */
checkdir();
/* check status */
@@ -231,7 +298,7 @@ getastat() /* check/set animation status */
}
/* assume it is dead */
}
- if (strcmp(cfname, astat.cfname) && astat.tnext != 0) { /* other's */
+ if (strcmp(cfname, astat.cfname) && astat.pid != 0) { /* other's */
fprintf(stderr, "%s: unfinished job \"%s\"\n",
progname, astat.cfname);
return(-1);
@@ -301,6 +368,7 @@ checkdir() /* make sure we have our directory */
setdefaults() /* set default values */
{
extern char *atos();
+ int decades;
char buf[256];
if (vdef(ANIMATE)) {
@@ -334,7 +402,9 @@ setdefaults() /* set default values */
quit(1);
}
if (!vdef(BASENAME)) {
- sprintf(buf, "%s/frame%%03d", vval(DIRECTORY));
+ decades = (int)log10((double)vint(END)) + 1;
+ if (decades < 3) decades = 3;
+ sprintf(buf, "%s/frame%%0%dd", vval(DIRECTORY), decades);
vval(BASENAME) = savqstr(buf);
vdef(BASENAME)++;
}
@@ -446,28 +516,35 @@ char *rfargs;
char combuf[256];
register int i;
register char *cp;
+ char *pippt;
/* create rad command */
sprintf(rendopt, " @%s/render.opt", vval(DIRECTORY));
sprintf(combuf,
"rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
rfargs, rendopt+2);
cp = combuf;
- while (*cp) cp++; /* match unset variables */
+ while (*cp) {
+ if (*cp == '|') pippt = cp;
+ cp++;
+ } /* match unset variables */
for (i = 0; mvar[i] >= 0; i++)
if (!vdef(mvar[i])) {
*cp++ = '|';
strcpy(cp, vnam(mvar[i]));
while (*cp) cp++;
+ pippt = NULL;
}
- sprintf(cp, ")[ \t]*=' > %s/radset.var", vval(DIRECTORY));
- cp += 11; /* point to file name */
- if (system(combuf)) {
- fprintf(stderr, "%s: error executing rad command:\n\t%s\n",
- progname, combuf);
- quit(1);
+ if (pippt != NULL)
+ strcpy(pippt, "> /dev/null"); /* nothing to match */
+ else {
+ sprintf(cp, ")[ \t]*=' > %s/radset.var", vval(DIRECTORY));
+ cp += 11; /* point to file name */
}
- loadvars(cp); /* load variables and remove file */
- unlink(cp);
+ system(combuf); /* ignore exit code */
+ if (pippt == NULL) { /* load variables and remove file */
+ loadvars(cp);
+ unlink(cp);
+ }
}
@@ -482,9 +559,9 @@ animate() /* run animation */
i = sscanf(vval(RESOLUTION), "%d %d %f", &xres, &yres, &pa);
mult = vflt(OVERSAMP);
if (i == 3) {
- sprintf(rresopt, "-x %d -y %d -pa %f", (int)(mult*xres),
+ sprintf(rresopt, "-x %d -y %d -pa %.3f", (int)(mult*xres),
(int)(mult*yres), pa);
- sprintf(fresopt, "-x %d -y %d -pa %f", xres, yres, pa);
+ sprintf(fresopt, "-x %d -y %d -pa %.3f", xres, yres, pa);
} else if (i) {
if (i == 1) yres = xres;
sprintf(rresopt, "-x %d -y %d", (int)(mult*xres),
@@ -501,7 +578,7 @@ animate() /* run animation */
progname, vnam(INTERP));
vval(INTERP) = "0";
}
- if (atoi(vval(MBLUR))) { /* can't handle this yet */
+ if (strcmp(vval(MBLUR),"0")) { /* can't handle this */
if (!nowarn)
fprintf(stderr,
"%s: resetting %s=0 for animation\n",
@@ -511,8 +588,8 @@ animate() /* run animation */
}
/* figure # frames per batch */
d1 = mult*xres*mult*yres*4; /* space for orig. picture */
- if ((i=vint(INTERP)) || atoi(vval(MBLUR)))
- d1 += mult*xres*mult*yres*4; /* space for z-buffer */
+ if ((i=vint(INTERP)) || getblur(NULL) > 1)
+ d1 += mult*xres*mult*yres*sizeof(float); /* Z-buffer */
d2 = xres*yres*4; /* space for final picture */
frames_batch = (i+1)*(vflt(DISKSPACE)*1048576.-d1)/(d1+i*d2);
if (frames_batch < i+2) {
@@ -521,9 +598,7 @@ animate() /* run animation */
quit(1);
}
/* initialize archive argument list */
- i = 16;
- if (vdef(ARCHIVE) && strlen(vval(ARCHIVE)) > i)
- i = strlen(vval(ARCHIVE));
+ i = vdef(ARCHIVE) ? strlen(vval(ARCHIVE))+132 : 132;
arcnext = arcfirst = arcargs + i;
/* initialize status file */
if (astat.rnext == 0)
@@ -627,7 +702,7 @@ filterframes() /* catch up with filtering */
transferframes() /* catch up with picture transfers */
{
- char combuf[10240];
+ char combuf[10240], *fbase;
register char *cp;
register int i;
@@ -638,12 +713,19 @@ transferframes() /* catch up with picture transfers
putastat(); /* update status */
return;
}
- strcpy(combuf, vval(TRANSFER)); /* start transfer command */
- cp = combuf + strlen(combuf);
+ strcpy(combuf, "cd "); /* start transfer command */
+ fbase = dirfile(cp = combuf+3, vval(BASENAME));
+ if (*cp) {
+ while (*++cp) ;
+ *cp++ = ';'; *cp++ = ' ';
+ } else
+ cp = combuf;
+ strcpy(cp, vval(TRANSFER));
+ while (*cp) cp++;
/* make argument list */
for (i = astat.tnext; i < astat.fnext; i++) {
*cp++ = ' ';
- sprintf(cp, vval(BASENAME), i);
+ sprintf(cp, fbase, i);
while (*cp) cp++;
strcpy(cp, ".pic");
cp += 4;
@@ -680,8 +762,10 @@ walkwait(first, last, vfn) /* walk-through frames */
int first, last;
char *vfn;
{
+ double blurf;
+ int nblur = getblur(&blurf);
char combuf[2048];
- char *inspoint;
+ register char *inspoint;
register int i;
if (!noaction && vint(INTERP)) /* create dummy frames */
@@ -692,12 +776,21 @@ char *vfn;
close(open(combuf, O_RDONLY|O_CREAT, 0666));
}
/* create command */
- sprintf(combuf, "rpict%s -w0", rendopt);
- if (vint(INTERP) || atoi(vval(MBLUR)))
- sprintf(combuf+strlen(combuf), " -z %s.zbf", vval(BASENAME));
- sprintf(combuf+strlen(combuf), " -o %s.unf %s -S %d",
+ sprintf(combuf, "rpict%s%s -w0", rendopt,
+ viewopt(getview(first>1 ? first-1 : 1)));
+ inspoint = combuf;
+ while (*inspoint) inspoint++;
+ if (nblur) {
+ sprintf(inspoint, " -pm %.3f", blurf/nblur);
+ while (*inspoint) inspoint++;
+ }
+ if (nblur > 1 || vint(INTERP)) {
+ sprintf(inspoint, " -z %s.zbf", vval(BASENAME));
+ while (*inspoint) inspoint++;
+ }
+ sprintf(inspoint, " -o %s.unf %s -S %d",
vval(BASENAME), rresopt, first);
- inspoint = combuf + strlen(combuf);
+ while (*inspoint) inspoint++;
sprintf(inspoint, " %s < %s", vval(OCTREE), vfn);
/* run in parallel */
i = (last-first+1)/(vint(INTERP)+1);
@@ -723,6 +816,8 @@ int frame;
{
static int *rfrm; /* list of recovered frames */
static int nrfrms = 0;
+ double blurf;
+ int nblur = getblur(&blurf);
char combuf[2048];
char fname[128];
register char *cp;
@@ -738,8 +833,13 @@ int frame;
vval(ANIMATE), frame, rendopt);
else
sprintf(combuf, "rpict%s -w0", rendopt);
- cp = combuf + strlen(combuf);
- if (vint(INTERP) || atoi(vval(MBLUR))) {
+ cp = combuf;
+ while (*cp) cp++;
+ if (nblur) {
+ sprintf(cp, " -pm %.3f", blurf/nblur);
+ while (*cp) cp++;
+ }
+ if (nblur > 1 || vint(INTERP)) {
sprintf(cp, " -z %s.zbf", fname);
while (*cp) cp++;
}
@@ -784,22 +884,40 @@ archive() /* archive and remove renderings */
{
#define RMCOML (sizeof(rmcom)-1)
static char rmcom[] = "rm -f";
- register int i;
+ char basedir[128];
+ int dlen, alen;
+ register int j;
if (arcnext == arcfirst)
return; /* nothing to do */
+ dirfile(basedir, vval(BASENAME));
+ dlen = strlen(basedir);
if (vdef(ARCHIVE)) { /* run archive command */
- i = strlen(vval(ARCHIVE));
- strncpy(arcfirst-i, vval(ARCHIVE), i);
- if (runcom(arcfirst-i)) {
+ alen = strlen(vval(ARCHIVE));
+ if (dlen) {
+ j = alen + dlen + 5;
+ strncpy(arcfirst-j, "cd ", 3);
+ strncpy(arcfirst-j+3, basedir, dlen);
+ (arcfirst-j)[dlen+3] = ';'; (arcfirst-j)[dlen+4] = ' ';
+ } else
+ j = alen;
+ strncpy(arcfirst-alen, vval(ARCHIVE), alen);
+ if (runcom(arcfirst-j)) {
fprintf(stderr, "%s: error running archive command\n",
progname);
quit(1);
}
}
+ if (dlen) {
+ j = RMCOML + dlen + 5;
+ strncpy(arcfirst-j, "cd ", 3);
+ strncpy(arcfirst-j+3, basedir, dlen);
+ (arcfirst-j)[dlen+3] = ';'; (arcfirst-j)[dlen+4] = ' ';
+ } else
+ j = RMCOML;
/* run remove command */
strncpy(arcfirst-RMCOML, rmcom, RMCOML);
- runcom(arcfirst-RMCOML);
+ runcom(arcfirst-j);
arcnext = arcfirst; /* reset argument list */
#undef RMCOML
}
@@ -814,12 +932,14 @@ int rvr;
{
extern int frecover();
static int iter = 0;
- char fnbefore[128], fnafter[128];
+ double blurf;
+ int nblur = getblur(&blurf);
+ char fnbefore[128], fnafter[128], *fbase;
char combuf[1024], fname0[128], fname1[128];
int usepinterp, usepfilt, nora_rgbe;
int frseq[2];
/* check what is needed */
- usepinterp = atoi(vval(MBLUR));
+ usepinterp = (nblur > 1);
usepfilt = pfiltalways | ep==NULL;
if (ep != NULL && !strcmp(ep, "1"))
ep = "+0";
@@ -828,6 +948,7 @@ int rvr;
/* compute rendered views */
frseq[0] = frame - ((frame-1) % (vint(INTERP)+1));
frseq[1] = frseq[0] + vint(INTERP) + 1;
+ fbase = dirfile(NULL, vval(BASENAME));
if (frseq[1] > vint(END))
frseq[1] = vint(END);
if (frseq[1] == frame) { /* pfilt only */
@@ -837,14 +958,13 @@ int rvr;
} else if (frseq[0] == frame) { /* no interpolation needed */
if (!rvr && frame > 1+vint(INTERP)) { /* archive previous */
*arcnext++ = ' ';
- sprintf(arcnext, vval(BASENAME), frame-vint(INTERP)-1);
+ sprintf(arcnext, fbase, frame-vint(INTERP)-1);
while (*arcnext) arcnext++;
strcpy(arcnext, ".unf");
arcnext += 4;
- if (usepinterp || vint(INTERP)) { /* and z-buf */
+ if (usepinterp || vint(INTERP)) { /* and Z-buf */
*arcnext++ = ' ';
- sprintf(arcnext, vval(BASENAME),
- frame-vint(INTERP)-1);
+ sprintf(arcnext, fbase, frame-vint(INTERP)-1);
while (*arcnext) arcnext++;
strcpy(arcnext, ".zbf");
arcnext += 4;
@@ -864,34 +984,35 @@ int rvr;
if (usepinterp) { /* using pinterp */
if (rvr == 2 && recover(frseq[1])) /* recover after? */
return(1);
- if (atoi(vval(MBLUR))) {
- FILE *fp; /* motion blurring */
+ if (nblur > 1) { /* with pmblur */
sprintf(fname0, "%s/vw0%c", vval(DIRECTORY),
'a'+(iter%26));
- if ((fp = fopen(fname0, "w")) == NULL) {
- perror(fname0); quit(1);
- }
- fputs(VIEWSTR, fp);
- fprintview(vp, fp);
- putc('\n', fp); fclose(fp);
- if ((vp = getview(frame+1)) == NULL) {
- fprintf(stderr,
- "%s: unexpected error reading view for frame %d\n",
- progname, frame+1);
- quit(1);
- }
sprintf(fname1, "%s/vw1%c", vval(DIRECTORY),
'a'+(iter%26));
- if ((fp = fopen(fname1, "w")) == NULL) {
- perror(fname1); quit(1);
+ if (!noaction) {
+ FILE *fp; /* motion blurring */
+ if ((fp = fopen(fname0, "w")) == NULL) {
+ perror(fname0); quit(1);
+ }
+ fputs(VIEWSTR, fp);
+ fprintview(vp, fp);
+ putc('\n', fp); fclose(fp);
+ if ((vp = getview(frame+1)) == NULL) {
+ fprintf(stderr,
+ "%s: unexpected error reading view for frame %d\n",
+ progname, frame+1);
+ quit(1);
+ }
+ if ((fp = fopen(fname1, "w")) == NULL) {
+ perror(fname1); quit(1);
+ }
+ fputs(VIEWSTR, fp);
+ fprintview(vp, fp);
+ putc('\n', fp); fclose(fp);
}
- fputs(VIEWSTR, fp);
- fprintview(vp, fp);
- putc('\n', fp); fclose(fp);
sprintf(combuf,
- "(pmblur %s %d %s %s; rm -f %s %s) | pinterp -B",
- *sskip(vval(MBLUR)) ? sskip2(vval(MBLUR),1) : "1",
- atoi(vval(MBLUR)),
+ "(pmblur %.3f %d %s %s; rm -f %s %s) | pinterp -B",
+ blurf, nblur,
fname0, fname1, fname0, fname1);
iter++;
} else /* no blurring */
@@ -899,7 +1020,7 @@ int rvr;
strcat(combuf, viewopt(vp));
if (vbool(RTRACE))
sprintf(combuf+strlen(combuf), " -ff -fr '%s -w0 %s'",
- rendopt, vval(OCTREE));
+ rendopt+1, vval(OCTREE));
if (vdef(PINTERP))
sprintf(combuf+strlen(combuf), " %s", vval(PINTERP));
if (usepfilt)
@@ -970,12 +1091,12 @@ int n;
}
return(NULL);
}
- if (viewfp == NULL) { /* open file */
+ if (viewfp == NULL) { /* open file */
if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) {
perror(vval(VIEWFILE));
quit(1);
}
- } else if (n < viewnum) { /* rewind file */
+ } else if (n > 0 && n < viewnum) { /* rewind file */
if (viewnum == 1 && feof(viewfp))
return(&curview); /* just one view */
if (fseek(viewfp, 0L, 0) == EOF) {
@@ -985,9 +1106,16 @@ int n;
copystruct(&curview, &stdview);
viewnum = 0;
}
+ if (n < 0) { /* get next view */
+ register int c = getc(viewfp);
+ if (c == EOF)
+ return((VIEW *)NULL); /* that's it */
+ ungetc(c, viewfp);
+ n = viewnum + 1;
+ }
while (n > viewnum) { /* scan to desired view */
if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL)
- return(viewnum==1 ? &curview : NULL);
+ return(viewnum==1 ? &curview : (VIEW *)NULL);
if (isview(linebuf) && sscanview(&curview, linebuf) > 0)
viewnum++;
}
@@ -998,9 +1126,11 @@ int n;
int
countviews() /* count views in view file */
{
- register int n = 0;
+ int n;
- while (getview(n+1) != NULL)
+ if (getview(n=1) == NULL)
+ return(0);
+ while (getview(-1) != NULL)
n++;
return(n);
}
@@ -1020,10 +1150,12 @@ int n;
if (n == 0) { /* signal to close file */
if (expfp != NULL) {
fclose(expfp);
+ free((void *)exppos);
expfp = NULL;
}
return(NULL);
- }
+ } else if (n > vint(END)) /* request past end (error?) */
+ return(NULL);
if (!vdef(EXPOSURE)) /* no setting (auto) */
return(NULL);
if (isflt(vval(EXPOSURE))) /* always the same */
@@ -1061,13 +1193,15 @@ int n;
}
curfrm++;
cp = fskip(expval); /* check format */
- if (cp == NULL || *cp != '\n') {
+ if (cp != NULL)
+ while (isspace(*cp))
+ *cp++ = '\0';
+ if (cp == NULL || *cp) {
fprintf(stderr,
"%s: exposure format error on line %d\n",
vval(EXPOSURE), curfrm);
quit(1);
}
- *cp = '\0';
}
return(expval); /* return value */
}
@@ -1097,6 +1231,7 @@ int pn;
int status;
{
register PROC *pp;
+ register struct pslot *psl;
pp = ps->proc + pn;
if (pp->elen) { /* pass errors */
@@ -1108,9 +1243,24 @@ int status;
if (ps->hostname[0])
status = 1; /* because rsh doesn't return status */
}
+ lastpserver = NULL;
+ psl = findpslot(pp->pid); /* check for bruncom() slot */
+ if (psl->pid) {
+ if (status) {
+ if (psl->rcvf != NULL) /* attempt recovery */
+ status = (*psl->rcvf)(psl->fout);
+ if (status) {
+ fprintf(stderr,
+ "%s: error rendering frame %d\n",
+ progname, psl->fout);
+ quit(1);
+ }
+ lastpserver = ps;
+ }
+ psl->pid = 0; /* free process slot */
+ } else if (status)
+ lastpserver = ps;
freestr(pp->com); /* free command string */
- lastpid = pp->pid; /* record PID for bwait() */
- lastpserver = ps; /* record server for serverdown() */
return(status);
}
@@ -1118,6 +1268,8 @@ int status;
int
serverdown() /* check status of last process server */
{
+ if (lastpserver == NULL || !lastpserver->hostname[0])
+ return(0);
if (pserverOK(lastpserver)) /* server still up? */
return(0);
delpserver(lastpserver); /* else delete it */
@@ -1144,8 +1296,8 @@ int (*rf)();
printf("\t%s\n", com); /* echo command */
return(0);
}
- /* else start it when we can */
- while ((pid = startjob(NULL, savestr(com), donecom)) == -1)
+ com = savestr(com); /* else start it when we can */
+ while ((pid = startjob(NULL, com, donecom)) == -1)
bwait(1);
if (!silent) { /* echo command */
PSERVER *ps;
@@ -1167,24 +1319,13 @@ bwait(ncoms) /* wait for batch job(s) to finish */
int ncoms;
{
int status;
- register struct pslot *psl;
if (noaction)
return;
while ((status = wait4job(NULL, -1)) != -1) {
- psl = findpslot(lastpid);
- if (status) { /* attempt recovery */
- serverdown(); /* check server */
- if (psl->rcvf == NULL || (*psl->rcvf)(psl->fout)) {
- fprintf(stderr,
- "%s: error rendering frame %d\n",
- progname, psl->fout);
- quit(1);
- }
- }
- psl->pid = 0; /* free process slot */
- if (!--ncoms)
- return; /* done enough */
+ serverdown(); /* update server status */
+ if (--ncoms == 0)
+ break; /* done enough */
}
}
@@ -1196,8 +1337,10 @@ int maxcopies;
{
int retstatus = 0;
int hostcopies;
- char com1buf[10240], *com1, *endcom1;
+ char buf[10240], *com1, *s;
int status;
+ int pfd;
+ register int n;
register PSERVER *ps;
if (!silent)
@@ -1209,25 +1352,23 @@ int maxcopies;
for (ps = pslist; ps != NULL; ps = ps->next) {
hostcopies = 0;
if (maxcopies > 1 && ps->nprocs > 1 && ppins != NULL) {
- strcpy(com1=com1buf, com); /* build -PP command */
+ strcpy(com1=buf, com); /* build -PP command */
sprintf(com1+(ppins-com), " -PP %s/%s.persist",
vval(DIRECTORY), phostname(ps));
strcat(com1, ppins);
- endcom1 = com1 + strlen(com1);
- sprintf(endcom1, "; kill `sed -n '1s/^[^ ]* //p' %s/%s.persist`",
- vval(DIRECTORY), phostname(ps));
- } else {
+ } else
com1 = com;
- endcom1 = NULL;
+ while (maxcopies > 0) {
+ s = savestr(com1);
+ if (startjob(ps, s, donecom) != -1) {
+ sleep(20);
+ hostcopies++;
+ maxcopies--;
+ } else {
+ freestr(s);
+ break;
+ }
}
- while (maxcopies > 0 &&
- startjob(ps, savestr(com1), donecom) != -1) {
- sleep(10);
- hostcopies++;
- maxcopies--;
- if (endcom1 != NULL)
- *endcom1 = '\0';
- }
if (!silent && hostcopies) {
if (hostcopies > 1)
printf("\t%d duplicate processes", hostcopies);
@@ -1239,8 +1380,21 @@ int maxcopies;
}
/* wait for jobs to finish */
while ((status = wait4job(NULL, -1)) != -1)
- if (status)
- retstatus += !serverdown(); /* check server */
+ retstatus += status && !serverdown();
+ /* terminate parallel rpict's */
+ for (ps = pslist; ps != NULL; ps = ps->next) {
+ sprintf(buf, "%s/%s.persist", vval(DIRECTORY), phostname(ps));
+ if ((pfd = open(buf, O_RDONLY)) >= 0) {
+ n = read(pfd, buf, sizeof(buf)-1); /* get PID */
+ buf[n] = '\0';
+ close(pfd);
+ for (n = 0; buf[n] && !isspace(buf[n]); n++)
+ ;
+ /* terminate */
+ sprintf(buf, "kill -ALRM %d", atoi(buf+n));
+ wait4job(ps, startjob(ps, buf, NULL));
+ }
+ }
return(retstatus);
}
@@ -1278,4 +1432,57 @@ int vc;
fprintf(stderr, "%s: bad value for variable '%s'\n",
progname, vnam(vc));
quit(1);
+}
+
+
+char *
+dirfile(df, path) /* separate path into directory and file */
+char *df;
+register char *path;
+{
+ register int i;
+ int psep;
+
+ for (i = 0, psep = -1; path[i]; i++)
+ if (path[i] == '/')
+ psep = i;
+ if (df != NULL)
+ if (psep == 0) {
+ df[0] = '/';
+ df[1] = '\0';
+ } else if (psep > 0) {
+ strncpy(df, path, psep);
+ df[psep] = '\0';
+ } else
+ df[0] = '\0';
+ return(path+psep+1);
+}
+
+
+int
+getblur(double *bf) /* get # blur samples (and fraction) */
+{
+ double blurf;
+ int nblur;
+ char *s;
+
+ if (!vdef(MBLUR)) {
+ if (bf != NULL)
+ *bf = 0.0;
+ return(0);
+ }
+ blurf = atof(vval(MBLUR));
+ if (blurf < 0.0)
+ blurf = 0.0;
+ if (bf != NULL)
+ *bf = blurf;
+ if (blurf <= FTINY)
+ return(0);
+ s = sskip(vval(MBLUR));
+ if (!*s)
+ return(DEF_NBLUR);
+ nblur = atoi(s);
+ if (nblur <= 0)
+ return(1);
+ return(nblur);
}