ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimate.c
Revision: 2.1
Committed: Fri Jan 12 12:16:17 1996 UTC (28 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /* Copyright (c) 1995 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Radiance animation control program
9 */
10
11 #include "standard.h"
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include "view.h"
15 #include "vars.h"
16 /* input variables */
17 #define HOST 0 /* rendering host machine */
18 #define RENDER 1 /* rendering options */
19 #define PFILT 2 /* pfilt options */
20 #define PINTERP 3 /* pinterp options */
21 #define OCTREE 4 /* octree file name */
22 #define DIRECTORY 5 /* working (sub)directory */
23 #define BASENAME 6 /* output image base name */
24 #define VIEWFILE 7 /* animation frame views */
25 #define START 8 /* starting frame number */
26 #define END 9 /* ending frame number */
27 #define RIF 10 /* rad input file */
28 #define NEXTANIM 11 /* next animation file */
29 #define ANIMATE 12 /* animation command */
30 #define TRANSFER 13 /* frame transfer command */
31 #define ARCHIVE 14 /* archiving command */
32 #define INTERP 15 /* # frames to interpolate */
33 #define OVERSAMP 16 /* # times to oversample image */
34 #define MBLUR 17 /* samples for motion blur */
35 #define RTRACE 18 /* use rtrace with pinterp? */
36 #define DISKSPACE 19 /* how much disk space to use */
37 #define RESOLUTION 20 /* desired final resolution */
38 #define EXPOSURE 21 /* how to compute exposure */
39
40 int NVARS = 22; /* total number of variables */
41
42 VARIABLE vv[] = { /* variable-value pairs */
43 {"host", 4, 0, NULL, NULL},
44 {"render", 3, 0, NULL, catvalues},
45 {"pfilt", 2, 0, NULL, catvalues},
46 {"pinterp", 2, 0, NULL, catvalues},
47 {"OCTREE", 3, 0, NULL, onevalue},
48 {"DIRECTORY", 3, 0, NULL, onevalue},
49 {"BASENAME", 3, 0, NULL, onevalue},
50 {"VIEWFILE", 2, 0, NULL, onevalue},
51 {"START", 2, 0, NULL, intvalue},
52 {"END", 2, 0, NULL, intvalue},
53 {"RIF", 3, 0, NULL, onevalue},
54 {"NEXTANIM", 3, 0, NULL, onevalue},
55 {"ANIMATE", 2, 0, NULL, onevalue},
56 {"TRANSFER", 2, 0, NULL, onevalue},
57 {"ARCHIVE", 2, 0, NULL, onevalue},
58 {"INTERP", 3, 0, NULL, intvalue},
59 {"OVERSAMP", 2, 0, NULL, fltvalue},
60 {"MBLUR", 2, 0, NULL, onevalue},
61 {"RTRACE", 2, 0, NULL, boolvalue},
62 {"DISKSPACE", 3, 0, NULL, fltvalue},
63 {"RESOLUTION", 3, 0, NULL, onevalue},
64 {"EXPOSURE", 3, 0, NULL, onevalue},
65 };
66
67 #define SFNAME "STATUS" /* status file name */
68
69 struct {
70 char host[64]; /* control host name */
71 int pid; /* control process id */
72 char cfname[128]; /* control file name */
73 int rnext; /* next frame to render */
74 int fnext; /* next frame to filter */
75 int tnext; /* next frame to transfer */
76 } astat; /* animation status */
77
78 char *progname; /* our program name */
79 char *cfname; /* our control file name */
80
81 int nowarn = 0; /* turn warnings off? */
82 int silent = 0; /* silent mode? */
83 int noaction = 0; /* take no action? */
84
85 char rendopt[2048] = ""; /* rendering options */
86 char rresopt[32]; /* rendering resolution options */
87 char fresopt[32]; /* filter resolution options */
88 int pfiltalways; /* always use pfilt? */
89
90 VIEW *getview();
91 char *getexp();
92
93
94 main(argc, argv)
95 int argc;
96 char *argv[];
97 {
98 int explicate = 0;
99 int i;
100
101 progname = argv[0]; /* get arguments */
102 for (i = 1; i < argc && argv[i][0] == '-'; i++)
103 switch (argv[i][1]) {
104 case 'e': /* print variables */
105 explicate++;
106 break;
107 case 'w': /* turn off warnings */
108 nowarn++;
109 break;
110 case 's': /* silent mode */
111 silent++;
112 break;
113 case 'n': /* take no action */
114 noaction++;
115 break;
116 default:
117 goto userr;
118 }
119 if (i != argc-1)
120 goto userr;
121 cfname = argv[i];
122 /* load variables */
123 loadvars(cfname);
124 /* did we get DIRECTORY? */
125 checkdir();
126 /* check status */
127 if (getastat() < 0) {
128 fprintf(stderr, "%s: exiting\n", progname);
129 quit(1);
130 }
131 /* pfilt always if options given */
132 pfiltalways = vdef(PFILT);
133 /* load RIF if any */
134 if (vdef(RIF))
135 getradfile(vval(RIF));
136 /* set defaults */
137 setdefaults();
138 /* print variables */
139 if (explicate)
140 printvars(stdout);
141 /* run animation */
142 animate();
143 /* all done */
144 if (vdef(NEXTANIM)) {
145 argv[i] = vval(NEXTANIM); /* just change input file */
146 if (!silent)
147 printargs(argc, argv, stdout);
148 if (!noaction) {
149 execvp(progname, argv); /* pass to next */
150 quit(1); /* shouldn't return */
151 }
152 }
153 quit(0);
154 userr:
155 fprintf(stderr, "Usage: %s [-s][-n][-w][-e] anim_file\n", progname);
156 quit(1);
157 }
158
159
160 getastat() /* check/set animation status */
161 {
162 char buf[256];
163 FILE *fp;
164
165 sprintf(buf, "%s/%s", vval(DIRECTORY), SFNAME);
166 if ((fp = fopen(buf, "r")) == NULL) {
167 if (errno != ENOENT) {
168 perror(buf);
169 return(-1);
170 }
171 astat.rnext = astat.fnext = astat.tnext = 0;
172 goto setours;
173 }
174 if (fscanf(fp, "Control host: %s\n", astat.host) != 1)
175 goto fmterr;
176 if (fscanf(fp, "Control PID: %d\n", &astat.pid) != 1)
177 goto fmterr;
178 if (fscanf(fp, "Control file: %s\n", astat.cfname) != 1)
179 goto fmterr;
180 if (fscanf(fp, "Next render: %d\n", &astat.rnext) != 1)
181 goto fmterr;
182 if (fscanf(fp, "Next filter: %d\n", &astat.fnext) != 1)
183 goto fmterr;
184 if (fscanf(fp, "Next transfer: %d\n", &astat.tnext) != 1)
185 goto fmterr;
186 fclose(fp);
187 if (astat.pid != 0) { /* thinks it's still running */
188 gethostname(buf, sizeof(buf));
189 if (strcmp(buf, astat.host)) {
190 fprintf(stderr,
191 "%s: process %d may still be running on host %s\n",
192 progname, astat.pid, astat.host);
193 return(-1);
194 }
195 if (kill(astat.pid, 0) != -1 || errno != ESRCH) {
196 fprintf(stderr, "%s: process %d is still running\n",
197 progname, astat.pid);
198 return(-1);
199 }
200 /* assume it is dead */
201 }
202 if (strcmp(cfname, astat.cfname) && astat.tnext != 0) { /* other's */
203 fprintf(stderr, "%s: unfinished job \"%s\"\n",
204 progname, astat.cfname);
205 return(-1);
206 }
207 setours: /* set our values */
208 gethostname(astat.host, sizeof(astat.host));
209 astat.pid = getpid();
210 strcpy(astat.cfname, cfname);
211 return(0);
212 fmterr:
213 fprintf(stderr, "%s: format error in status file \"%s\"\n",
214 progname, buf);
215 fclose(fp);
216 return(-1);
217 }
218
219
220 putastat() /* put out current status */
221 {
222 char buf[256];
223 FILE *fp;
224
225 sprintf(buf, "%s/%s", vval(DIRECTORY), SFNAME);
226 if ((fp = fopen(buf, "w")) == NULL) {
227 perror(buf);
228 quit(1);
229 }
230 fprintf(fp, "Control host: %s\n", astat.host);
231 fprintf(fp, "Control PID: %d\n", astat.pid);
232 fprintf(fp, "Control file: %s\n", astat.cfname);
233 fprintf(fp, "Next render: %d\n", astat.rnext);
234 fprintf(fp, "Next filter: %d\n", astat.fnext);
235 fprintf(fp, "Next transfer: %d\n", astat.tnext);
236 fclose(fp);
237 }
238
239
240 checkdir() /* make sure we have our directory */
241 {
242 struct stat stb;
243
244 if (!vdef(DIRECTORY)) {
245 fprintf(stderr, "%s: %s undefined\n",
246 progname, vnam(DIRECTORY));
247 quit(1);
248 }
249 if (stat(vval(DIRECTORY), &stb) == -1) {
250 if (errno == ENOENT && mkdir(vval(DIRECTORY), 0777) == 0)
251 return;
252 perror(vval(DIRECTORY));
253 quit(1);
254 }
255 if (!(stb.st_mode & S_IFDIR)) {
256 fprintf(stderr, "%s: not a directory\n", vval(DIRECTORY));
257 quit(1);
258 }
259 }
260
261
262 setdefaults() /* set default values */
263 {
264 char buf[256];
265
266 if (vdef(OCTREE) == vdef(ANIMATE)) {
267 fprintf(stderr, "%s: either %s or %s must be defined\n",
268 progname, vnam(OCTREE), vnam(ANIMATE));
269 quit(1);
270 }
271 if (!vdef(VIEWFILE)) {
272 fprintf(stderr, "%s: %s undefined\n", progname, vnam(VIEWFILE));
273 quit(1);
274 }
275 if (!vdef(START)) {
276 vval(START) = "1";
277 vdef(START)++;
278 }
279 if (!vdef(END)) {
280 sprintf(buf, "%d", countviews());
281 vval(END) = savqstr(buf);
282 vdef(END)++;
283 }
284 if (!vdef(BASENAME)) {
285 sprintf(buf, "%s/frame%%03d", vval(DIRECTORY));
286 vval(BASENAME) = savqstr(buf);
287 vdef(BASENAME)++;
288 }
289 if (!vdef(RESOLUTION)) {
290 vval(RESOLUTION) = "640";
291 vdef(RESOLUTION)++;
292 }
293 if (!vdef(OVERSAMP)) {
294 vval(OVERSAMP) = "2";
295 vdef(OVERSAMP)++;
296 }
297 if (!vdef(INTERP)) {
298 vval(INTERP) = "0";
299 vdef(INTERP)++;
300 }
301 if (!vdef(MBLUR)) {
302 vval(MBLUR) = "0";
303 vdef(MBLUR)++;
304 }
305 if (!vdef(RTRACE)) {
306 vval(RTRACE) = "F";
307 vdef(RTRACE)++;
308 }
309 if (!vdef(DISKSPACE)) {
310 if (!nowarn)
311 fprintf(stderr,
312 "%s: warning - no %s setting, assuming 100 Mbytes available\n",
313 progname, vnam(DISKSPACE));
314 vval(DISKSPACE) = "100";
315 vdef(DISKSPACE)++;
316 }
317 /* append rendering options */
318 if (vdef(RENDER))
319 sprintf(rendopt+strlen(rendopt), " %s", vval(RENDER));
320 }
321
322
323 getradfile(rfname) /* run rad and get needed variables */
324 char *rfname;
325 {
326 static short mvar[] = {OCTREE,PFILT,RESOLUTION,EXPOSURE,-1};
327 char combuf[256];
328 register int i;
329 register char *cp;
330 /* create rad command */
331 sprintf(rendopt, " @%s/render.opt", vval(DIRECTORY));
332 sprintf(combuf,
333 "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
334 rfname, rendopt+2);
335 cp = combuf;
336 while (*cp) cp++; /* match unset variables */
337 for (i = 0; mvar[i] >= 0; i++)
338 if (!vdef(mvar[i])) {
339 *cp++ = '|';
340 strcpy(cp, vnam(mvar[i]));
341 while (*cp) cp++;
342 }
343 sprintf(cp, ")[ \t]*=' > %s/radset.var", vval(DIRECTORY));
344 cp += 11; /* point to file name */
345 if (system(combuf)) {
346 fprintf(stderr, "%s: bad rad input file \"%s\"\n",
347 progname, rfname);
348 quit(1);
349 }
350 loadvars(cp); /* load variables and remove file */
351 unlink(cp);
352 }
353
354
355 animate() /* run animation */
356 {
357 int xres, yres;
358 float pa, mult;
359 int frames_batch;
360 register int i;
361 double d1, d2;
362 /* compute rpict resolution */
363 i = sscanf(vval(RESOLUTION), "%d %d %f", &xres, &yres, &pa);
364 mult = vflt(OVERSAMP);
365 if (i == 3) {
366 sprintf(rresopt, "-x %d -y %d -pa %f", (int)(mult*xres),
367 (int)(mult*yres), pa);
368 sprintf(fresopt, "-x %d -y %d -pa %f", xres, yres, pa);
369 } else if (i) {
370 if (i == 1) yres = xres;
371 sprintf(rresopt, "-x %d -y %d", (int)(mult*xres),
372 (int)(mult*yres));
373 sprintf(fresopt, "-x %d -y %d -pa 1", xres, yres);
374 } else
375 badvalue(RESOLUTION);
376 /* consistency checks */
377 if (vdef(ANIMATE)) {
378 if (vint(INTERP)) {
379 if (!nowarn)
380 fprintf(stderr,
381 "%s: resetting %s=0 for animation\n",
382 progname, vnam(INTERP));
383 vval(INTERP) = "0";
384 }
385 if (atoi(vval(MBLUR))) { /* can't handle this yet */
386 if (!nowarn)
387 fprintf(stderr,
388 "%s: resetting %s=0 for animation\n",
389 progname, vnam(MBLUR));
390 vval(MBLUR) = "0";
391 }
392 }
393 /* figure # frames per batch */
394 d1 = mult*xres*mult*yres*4; /* space for orig. picture */
395 if ((i=vint(INTERP)) || atoi(vval(MBLUR)))
396 d1 += mult*xres*mult*yres*4; /* space for z-buffer */
397 d2 = xres*yres*4; /* space for final picture */
398 frames_batch = (i+1)*(vflt(DISKSPACE)*1048576.-d1)/(d1+i*d2);
399 if (frames_batch < i+2) {
400 fprintf(stderr, "%s: insufficient disk space allocated\n",
401 progname);
402 quit(1);
403 }
404 /* initialize status file */
405 if (astat.rnext == 0)
406 astat.rnext = astat.fnext = astat.tnext = vint(START);
407 putastat();
408 /* render in batches */
409 while (astat.rnext <= vint(END)) {
410 renderframes(frames_batch);
411 filterframes();
412 transferframes();
413 }
414 /* mark status as finished */
415 astat.pid = 0;
416 putastat();
417 /* close open files */
418 getview(0);
419 getexp(0);
420 }
421
422
423 renderframes(nframes) /* render next nframes frames */
424 int nframes;
425 {
426 static char vendbuf[16];
427 VIEW *vp;
428 FILE *fp = NULL;
429 char vfname[128];
430 int lastframe;
431 register int i;
432
433 if (astat.tnext < astat.rnext) /* other work to do first */
434 return;
435 /* create batch view file */
436 if (!vdef(ANIMATE)) {
437 sprintf(vfname, "%s/anim.vf", vval(DIRECTORY));
438 if ((fp = fopen(vfname, "w")) == NULL) {
439 perror(vfname);
440 quit(1);
441 }
442 }
443 /* bound batch properly */
444 lastframe = astat.rnext + nframes - 1;
445 if ((lastframe-1) % (vint(INTERP)+1)) /* need even interval */
446 lastframe += vint(INTERP)+1 - ((lastframe-1)%(vint(INTERP)+1));
447 if (lastframe > vint(END)) /* check for end */
448 lastframe = vint(END);
449 /* render each view */
450 for (i = astat.rnext; i <= lastframe; i++) {
451 if ((vp = getview(i)) == NULL) {
452 if (!nowarn)
453 fprintf(stderr,
454 "%s: ran out of views before last frame\n",
455 progname);
456 sprintf(vval(END)=vendbuf, "%d", i-1);
457 lastframe = i - 1;
458 break;
459 }
460 if (vdef(ANIMATE)) /* animate frame */
461 animrend(i, vp);
462 else { /* else record it */
463 fputs(VIEWSTR, fp);
464 fprintview(vp, fp);
465 putc('\n', fp);
466 }
467 }
468 if (vdef(ANIMATE)) /* wait for renderings to finish */
469 animwait(0);
470 else { /* else if walk-through */
471 fclose(fp); /* close view file */
472 walkwait(astat.rnext, lastframe, vfname); /* walk it */
473 unlink(vfname); /* remove view file */
474 }
475 if (vdef(ARCHIVE)) /* archive results */
476 archive(astat.rnext, lastframe);
477 astat.rnext = i; /* update status */
478 putastat();
479 }
480
481
482 filterframes() /* catch up with filtering */
483 {
484 VIEW *vp;
485 register int i;
486
487 if (astat.tnext < astat.fnext) /* other work to do first */
488 return;
489 /* filter each view */
490 for (i = astat.fnext; i < astat.rnext; i++) {
491 if ((vp = getview(i)) == NULL) { /* get view i */
492 fprintf(stderr,
493 "%s: unexpected error reading view for frame %d\n",
494 progname, i);
495 quit(1);
496 }
497 dofilt(i, vp, getexp(i)); /* filter frame */
498 }
499 filtwait(0); /* wait for filter processes */
500 astat.fnext = i; /* update status */
501 putastat();
502 }
503
504
505 transferframes() /* catch up with picture transfers */
506 {
507 char combuf[10240];
508 register char *cp;
509 register int i;
510
511 if (astat.tnext >= astat.fnext) /* nothing to do, yet */
512 return;
513 if (!vdef(TRANSFER)) { /* no transfer function -- leave 'em */
514 astat.tnext = astat.fnext;
515 putastat(); /* update status */
516 return;
517 }
518 strcpy(combuf, vval(TRANSFER)); /* start transfer command */
519 cp = combuf + strlen(combuf);
520 /* make argument list */
521 for (i = astat.tnext; i < astat.fnext; i++) {
522 *cp++ = ' ';
523 sprintf(cp, vval(BASENAME), i);
524 while (*cp) cp++;
525 strcpy(cp, ".pic");
526 cp += 4;
527 }
528 if (runcom(combuf)) { /* transfer frames */
529 fprintf(stderr, "%s: error running transfer command\n",
530 progname);
531 quit(1);
532 }
533 astat.tnext = i; /* update status */
534 putastat();
535 }
536
537
538 animrend(frame, vp) /* start animation frame */
539 int frame;
540 VIEW *vp;
541 {
542 char combuf[2048];
543 char fname[128];
544
545 sprintf(fname, vval(BASENAME), frame);
546 strcat(fname, ".unf");
547 if (access(fname, F_OK) == 0)
548 return;
549 sprintf(combuf, "%s %d | rpict%s%s %s > %s", vval(ANIMATE), frame,
550 rendopt, viewopt(vp), rresopt, fname);
551 if (runcom(combuf)) {
552 fprintf(stderr, "%s: error rendering frame %d\n",
553 progname, frame);
554 quit(1);
555 }
556 }
557
558
559 animwait(nwait) /* wait for renderings to finish */
560 int nwait;
561 {
562 /* currently does nothing since parallel rendering not working */
563 }
564
565
566 walkwait(first, last, vfn) /* walk-through frames */
567 int first, last;
568 char *vfn;
569 {
570 char combuf[2048];
571 register int i;
572
573 if (!noaction && vint(INTERP)) /* create dummy frames */
574 for (i = first; i <= last; i++)
575 if (i < vint(END) && (i-1) % (vint(INTERP)+1)) {
576 sprintf(combuf, vval(BASENAME), i);
577 strcat(combuf, ".unf");
578 close(open(combuf, O_RDONLY|O_CREAT, 0666));
579 }
580 /* create command */
581 sprintf(combuf, "rpict%s ", rendopt);
582 if (vint(INTERP) || atoi(vval(MBLUR)))
583 sprintf(combuf+strlen(combuf), "-z %s.zbf ", vval(BASENAME));
584 sprintf(combuf+strlen(combuf), "-o %s.unf %s -S %d %s < %s",
585 vval(BASENAME), rresopt, first, vval(OCTREE), vfn);
586 if (runcom(combuf)) {
587 fprintf(stderr,
588 "%s: error rendering walk-through frames %d through %d\n",
589 progname, first, last);
590 quit(1);
591 }
592 if (!noaction && vint(INTERP)) /* remove dummy frames */
593 for (i = first; i <= last; i++)
594 if (i < vint(END) && (i-1) % (vint(INTERP)+1)) {
595 sprintf(combuf, vval(BASENAME), i);
596 strcat(combuf, ".unf");
597 unlink(combuf);
598 }
599 }
600
601
602 recover(frame) /* recover the specified frame */
603 int frame;
604 {
605 char combuf[2048];
606 char fname[128];
607 register char *cp;
608
609 sprintf(fname, vval(BASENAME), frame);
610 if (vdef(ANIMATE))
611 sprintf(combuf, "%s %d | rpict%s",
612 vval(ANIMATE), frame, rendopt);
613 else
614 sprintf(combuf, "rpict%s", rendopt);
615 cp = combuf + strlen(combuf);
616 if (vint(INTERP) || atoi(vval(MBLUR))) {
617 sprintf(cp, " -z %s.zbf", fname);
618 while (*cp) cp++;
619 }
620 sprintf(cp, " -ro %s.unf", fname);
621 while (*cp) cp++;
622 if (!vdef(ANIMATE)) {
623 *cp++ = ' ';
624 strcpy(cp, vval(OCTREE));
625 }
626 if (runcom(combuf)) {
627 fprintf(stderr, "%s: error recovering frame %d\n",
628 progname, frame);
629 quit(1);
630 }
631 }
632
633
634 archive(first, last) /* archive finished renderings */
635 int first, last;
636 {
637 char combuf[10240];
638 int offset;
639 struct stat stb;
640 register char *cp;
641 register int i;
642
643 strcpy(cp=combuf, vval(ARCHIVE));
644 while (*cp) cp++;
645 offset = cp - combuf;
646 *cp++ = ' '; /* make argument list */
647 for (i = first; i <= last; i++) {
648 sprintf(cp, vval(BASENAME), i);
649 strcat(cp, ".unf");
650 if (stat(cp, &stb) == 0 && stb.st_size > 0) { /* non-zero? */
651 while (*cp) cp++;
652 *cp++ = ' ';
653 sprintf(cp, vval(BASENAME), i);
654 strcat(cp, ".zbf");
655 if (access(cp, F_OK) == 0) { /* exists? */
656 while (*cp) cp++;
657 *cp++ = ' ';
658 }
659 }
660 }
661 *--cp = '\0';
662 if (cp <= combuf + offset) /* no files? */
663 return;
664 if (runcom(combuf)) { /* run archive command */
665 fprintf(stderr,
666 "%s: error running archive command on frames %d through %d\n",
667 progname, first, last);
668 quit(1);
669 }
670 }
671
672
673 dofilt(frame, vp, ep) /* filter frame */
674 int frame;
675 VIEW *vp;
676 char *ep;
677 {
678 char fnbefore[128], fnafter[128];
679 char combuf[1024], fname[128];
680 int usepinterp, usepfilt;
681 int frbefore, frafter, triesleft;
682 /* check what is needed */
683 usepinterp = atoi(vval(MBLUR));
684 usepfilt = pfiltalways | ep==NULL;
685 /* compute rendered views */
686 frbefore = frame - ((frame-1) % (vint(INTERP)+1));
687 frafter = frbefore + vint(INTERP) + 1;
688 if (frafter > vint(END))
689 frafter = vint(END);
690 if (frafter == frame) { /* pfilt only */
691 frbefore = frafter;
692 usepinterp = 0; /* update what's needed */
693 usepfilt |= vflt(OVERSAMP)>1.01 || strcmp(ep,"1");
694 triesleft = 2;
695 } else if (frbefore == frame) { /* no interpolation */
696 /* remove unneeded files */
697 if (frbefore-vint(INTERP)-1 >= 1) {
698 sprintf(fname, vval(BASENAME), frbefore-vint(INTERP)-1);
699 sprintf(combuf, "rm -f %s.unf %s.zbf", fname, fname);
700 runcom(combuf);
701 }
702 /* update what's needed */
703 if (usepinterp)
704 triesleft = 3;
705 else {
706 usepfilt |= vflt(OVERSAMP)>1.01 || strcmp(ep,"1");
707 triesleft = 2;
708 }
709 } else { /* interpolation needed */
710 usepinterp++;
711 triesleft = 3;
712 }
713 if (frafter >= astat.rnext) { /* next batch unavailable */
714 frafter = frbefore;
715 if (triesleft > 2)
716 triesleft = 2;
717 }
718 sprintf(fnbefore, vval(BASENAME), frbefore);
719 sprintf(fnafter, vval(BASENAME), frafter);
720 tryit: /* generate command */
721 if (usepinterp) { /* using pinterp */
722 if (atoi(vval(MBLUR))) {
723 FILE *fp; /* motion blurring */
724 sprintf(fname, "%s/vw0", vval(DIRECTORY));
725 if ((fp = fopen(fname, "w")) == NULL) {
726 perror(fname); quit(1);
727 }
728 fputs(VIEWSTR, fp);
729 fprintview(vp, fp);
730 putc('\n', fp); fclose(fp);
731 if ((vp = getview(frame+1)) == NULL) {
732 fprintf(stderr,
733 "%s: unexpected error reading view for frame %d\n",
734 progname, frame+1);
735 quit(1);
736 }
737 sprintf(fname, "%s/vw1", vval(DIRECTORY));
738 if ((fp = fopen(fname, "w")) == NULL) {
739 perror(fname); quit(1);
740 }
741 fputs(VIEWSTR, fp);
742 fprintview(vp, fp);
743 putc('\n', fp); fclose(fp);
744 sprintf(combuf,
745 "(pmblur %s %d %s/vw0 %s/vw1; rm -f %s/vw0 %s/vw1) | pinterp -B",
746 *sskip(vval(MBLUR)) ? sskip(vval(MBLUR)) : "1",
747 atoi(vval(MBLUR)), vval(DIRECTORY),
748 vval(DIRECTORY), vval(DIRECTORY),
749 vval(DIRECTORY), vval(DIRECTORY));
750 } else /* no blurring */
751 strcpy(combuf, "pinterp");
752 strcat(combuf, viewopt(vp));
753 if (vbool(RTRACE))
754 sprintf(combuf+strlen(combuf), " -ff -fr '%s %s'",
755 rendopt, vval(OCTREE));
756 if (vdef(PINTERP))
757 sprintf(combuf+strlen(combuf), " %s", vval(PINTERP));
758 if (usepfilt)
759 sprintf(combuf+strlen(combuf), " %s", rresopt);
760 else
761 sprintf(combuf+strlen(combuf), " %s -e %s",
762 fresopt, ep);
763 sprintf(combuf+strlen(combuf), " %s.unf %s.zbf",
764 fnbefore, fnbefore);
765 if (frafter != frbefore)
766 sprintf(combuf+strlen(combuf), " %s.unf %s.zbf",
767 fnafter, fnafter);
768 if (usepfilt) { /* also pfilt */
769 if (vdef(PFILT))
770 sprintf(combuf+strlen(combuf), " | pfilt %s",
771 vval(PFILT));
772 else
773 strcat(combuf, " | pfilt");
774 if (ep != NULL)
775 sprintf(combuf+strlen(combuf), " -1 -e %s %s",
776 ep, fresopt);
777 else
778 sprintf(combuf+strlen(combuf), " %s", fresopt);
779 }
780 } else if (usepfilt) { /* pfilt only */
781 if (vdef(PFILT))
782 sprintf(combuf, "pfilt %s", vval(PFILT));
783 else
784 strcpy(combuf, "pfilt");
785 if (ep != NULL)
786 sprintf(combuf+strlen(combuf), " -1 -e %s %s %s.unf",
787 ep, fresopt, fnbefore);
788 else
789 sprintf(combuf+strlen(combuf), " %s %s.unf",
790 fresopt, fnbefore);
791 } else { /* else just check it */
792 sprintf(combuf, "ra_rgbe -r %s.unf", fnbefore);
793 }
794 /* output file name */
795 sprintf(fname, vval(BASENAME), frame);
796 sprintf(combuf+strlen(combuf), " > %s.pic", fname);
797 if (runcom(combuf)) /* run filter command */
798 switch (--triesleft) {
799 case 2: /* try to recover frafter */
800 recover(frafter);
801 goto tryit;
802 case 1: /* try to recover frbefore */
803 recover(frbefore);
804 goto tryit;
805 default: /* we've really failed */
806 fprintf(stderr,
807 "%s: unrecoverable filtering error on frame %d\n",
808 progname, frame);
809 quit(1);
810 }
811 }
812
813
814 filtwait(nwait) /* wait for filtering processes to finish */
815 int nwait;
816 {
817 /* currently does nothing since parallel filtering not working */
818 }
819
820
821 VIEW *
822 getview(n) /* get view number n */
823 int n;
824 {
825 static FILE *viewfp = NULL; /* view file pointer */
826 static int viewnum = 0; /* current view number */
827 static VIEW curview = STDVIEW; /* current view */
828 char linebuf[256];
829
830 if (n == 0) { /* signal to close file and clean up */
831 if (viewfp != NULL) {
832 fclose(viewfp);
833 viewfp = NULL;
834 viewnum = 0;
835 copystruct(&curview, &stdview);
836 }
837 return(NULL);
838 }
839 if (viewfp == NULL) { /* open file */
840 if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) {
841 perror(vval(VIEWFILE));
842 quit(1);
843 }
844 } else if (n < viewnum) { /* rewind file */
845 if (fseek(viewfp, 0L, 0) == EOF) {
846 perror(vval(VIEWFILE));
847 quit(1);
848 }
849 copystruct(&curview, &stdview);
850 viewnum = 0;
851 }
852 while (n > viewnum) { /* scan to desired view */
853 if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL)
854 return(NULL);
855 if (isview(linebuf) && sscanview(&curview, linebuf) > 0)
856 viewnum++;
857 }
858 return(&curview); /* return it */
859 }
860
861
862 int
863 countviews() /* count views in view file */
864 {
865 register int n = 0;
866
867 while (getview(n+1) != NULL)
868 n++;
869 return(n);
870 }
871
872
873 char *
874 getexp(n) /* get exposure for nth frame */
875 int n;
876 {
877 extern char *fskip();
878 static char expval[32];
879 static FILE *expfp = NULL;
880 static long *exppos;
881 static int curfrm;
882 register char *cp;
883
884 if (n == 0) { /* signal to close file */
885 if (expfp != NULL) {
886 fclose(expfp);
887 expfp = NULL;
888 }
889 return(NULL);
890 }
891 if (!vdef(EXPOSURE)) /* no setting (auto) */
892 return(NULL);
893 if (isflt(vval(EXPOSURE))) /* always the same */
894 return(vval(EXPOSURE));
895 if (expfp == NULL) { /* open exposure file */
896 if ((expfp = fopen(vval(EXPOSURE), "r")) == NULL) {
897 fprintf(stderr,
898 "%s: cannot open exposure file \"%s\"\n",
899 progname, vval(EXPOSURE));
900 quit(1);
901 }
902 curfrm = vint(END) + 1; /* init lookup tab. */
903 exppos = (long *)malloc(curfrm*sizeof(long *));
904 if (exppos == NULL) {
905 perror(progname);
906 quit(1);
907 }
908 while (curfrm--)
909 exppos[curfrm] = -1L;
910 curfrm = 0;
911 }
912 /* find position in file */
913 if (n-1 != curfrm && n != curfrm && exppos[n-1] >= 0 &&
914 fseek(expfp, exppos[curfrm=n-1], 0) == EOF) {
915 fprintf(stderr, "%s: seek error on exposure file\n", progname);
916 quit(1);
917 }
918 while (n > curfrm) { /* read exposure */
919 if (exppos[curfrm] < 0)
920 exppos[curfrm] = ftell(expfp);
921 if (fgets(expval, sizeof(expval), expfp) == NULL) {
922 fprintf(stderr, "%s: too few exposures\n",
923 vval(EXPOSURE));
924 quit(1);
925 }
926 curfrm++;
927 cp = fskip(expval); /* check format */
928 if (cp == NULL || *cp != '\n') {
929 fprintf(stderr,
930 "%s: exposure format error on line %d\n",
931 vval(EXPOSURE), curfrm);
932 quit(1);
933 }
934 *cp = '\0';
935 }
936 return(expval); /* return value */
937 }
938
939
940 runcom(cs) /* run command */
941 char *cs;
942 {
943 if (!silent) /* echo it */
944 printf("\t%s\n", cs);
945 if (noaction)
946 return(0);
947 fflush(stdout); /* flush output and pass to shell */
948 return(system(cs));
949 }
950
951
952 rmfile(fn) /* remove a file */
953 char *fn;
954 {
955 if (!silent)
956 #ifdef MSDOS
957 printf("\tdel %s\n", fn);
958 #else
959 printf("\trm -f %s\n", fn);
960 #endif
961 if (noaction)
962 return(0);
963 return(unlink(fn));
964 }
965
966
967 badvalue(vc) /* report bad variable value and exit */
968 int vc;
969 {
970 fprintf(stderr, "%s: bad value for variable '%s'\n",
971 progname, vnam(vc));
972 quit(1);
973 }