--- ray/src/util/ranimate.c 1996/05/30 17:00:10 2.14 +++ ray/src/util/ranimate.c 1998/03/03 19:36:43 2.26 @@ -93,7 +93,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,15 +108,14 @@ 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(); extern time_t fdate(), time(); @@ -151,6 +150,8 @@ char *argv[]; cfname = argv[i]; /* load variables */ loadvars(cfname); + /* check variables */ + checkvalues(); /* did we get DIRECTORY? */ checkdir(); /* check status */ @@ -231,7 +232,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 +302,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 +336,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 +450,39 @@ 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 (pippt != NULL) + strcpy(pippt, "> /dev/null"); /* nothing to match */ + else { + 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); } - loadvars(cp); /* load variables and remove file */ - unlink(cp); + if (pippt == NULL) { /* load variables and remove file */ + loadvars(cp); + unlink(cp); + } } @@ -482,9 +497,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), @@ -521,9 +536,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 +640,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 +651,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; @@ -692,7 +712,8 @@ char *vfn; close(open(combuf, O_RDONLY|O_CREAT, 0666)); } /* create command */ - sprintf(combuf, "rpict%s -w0", rendopt); + sprintf(combuf, "rpict%s%s -w0", rendopt, + viewopt(getview(first>1 ? first-1 : 1))); 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", @@ -784,22 +805,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,7 +853,7 @@ int rvr; { extern int frecover(); static int iter = 0; - char fnbefore[128], fnafter[128]; + char fnbefore[128], fnafter[128], *fbase; char combuf[1024], fname0[128], fname1[128]; int usepinterp, usepfilt, nora_rgbe; int frseq[2]; @@ -828,6 +867,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 +877,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 */ *arcnext++ = ' '; - sprintf(arcnext, vval(BASENAME), - frame-vint(INTERP)-1); + sprintf(arcnext, fbase, frame-vint(INTERP)-1); while (*arcnext) arcnext++; strcpy(arcnext, ".zbf"); arcnext += 4; @@ -865,29 +904,31 @@ int rvr; if (rvr == 2 && recover(frseq[1])) /* recover after? */ return(1); if (atoi(vval(MBLUR))) { - FILE *fp; /* motion blurring */ 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", @@ -899,7 +940,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 +1011,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 +1026,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 +1046,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); } @@ -1101,6 +1151,7 @@ int pn; int status; { register PROC *pp; + register struct pslot *psl; pp = ps->proc + pn; if (pp->elen) { /* pass errors */ @@ -1112,9 +1163,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); } @@ -1122,6 +1188,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 */ @@ -1148,8 +1216,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; @@ -1171,24 +1239,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 */ } } @@ -1200,8 +1257,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) @@ -1213,25 +1272,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); @@ -1243,8 +1300,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); } @@ -1282,4 +1352,28 @@ 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); }