ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.44
Committed: Fri Aug 18 10:39:56 1995 UTC (28 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.43: +4 -1 lines
Log Message:
added cylindrical view type

File Contents

# Content
1 /* Copyright (c) 1994 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * Executive program for oconv, rpict and pfilt
9 */
10
11 #include "standard.h"
12 #include "paths.h"
13 #include <ctype.h>
14 #include <sys/types.h>
15
16
17 typedef struct {
18 char *name; /* variable name */
19 short nick; /* # characters required for nickname */
20 short nass; /* # assignments made */
21 char *value; /* assigned value(s) */
22 int (*fixval)(); /* assignment checking function */
23 } VARIABLE;
24
25 int onevalue(), catvalues(), boolvalue(),
26 qualvalue(), fltvalue(), intvalue();
27
28 /* variables */
29 #define OBJECT 0 /* object files */
30 #define SCENE 1 /* scene files */
31 #define MATERIAL 2 /* material files */
32 #define ILLUM 3 /* mkillum input files */
33 #define MKILLUM 4 /* mkillum options */
34 #define RENDER 5 /* rendering options */
35 #define OCONV 6 /* oconv options */
36 #define PFILT 7 /* pfilt options */
37 #define VIEW 8 /* view(s) for picture(s) */
38 #define ZONE 9 /* simulation zone */
39 #define QUALITY 10 /* desired rendering quality */
40 #define OCTREE 11 /* octree file name */
41 #define PICTURE 12 /* picture file name */
42 #define AMBFILE 13 /* ambient file name */
43 #define OPTFILE 14 /* rendering options file */
44 #define EXPOSURE 15 /* picture exposure setting */
45 #define RESOLUTION 16 /* maximum picture resolution */
46 #define UP 17 /* view up (X, Y or Z) */
47 #define INDIRECT 18 /* indirection in lighting */
48 #define DETAIL 19 /* level of scene detail */
49 #define PENUMBRAS 20 /* shadow penumbras are desired */
50 #define VARIABILITY 21 /* level of light variability */
51 #define REPORT 22 /* report frequency and errfile */
52 #define RAWSAVE 23 /* save raw picture file */
53 /* total number of variables */
54 #define NVARS 24
55
56 VARIABLE vv[NVARS] = { /* variable-value pairs */
57 {"objects", 3, 0, NULL, catvalues},
58 {"scene", 3, 0, NULL, catvalues},
59 {"materials", 3, 0, NULL, catvalues},
60 {"illum", 3, 0, NULL, catvalues},
61 {"mkillum", 3, 0, NULL, catvalues},
62 {"render", 3, 0, NULL, catvalues},
63 {"oconv", 3, 0, NULL, catvalues},
64 {"pfilt", 2, 0, NULL, catvalues},
65 {"view", 2, 0, NULL, NULL},
66 {"ZONE", 2, 0, NULL, onevalue},
67 {"QUALITY", 3, 0, NULL, qualvalue},
68 {"OCTREE", 3, 0, NULL, onevalue},
69 {"PICTURE", 3, 0, NULL, onevalue},
70 {"AMBFILE", 3, 0, NULL, onevalue},
71 {"OPTFILE", 3, 0, NULL, onevalue},
72 {"EXPOSURE", 3, 0, NULL, fltvalue},
73 {"RESOLUTION", 3, 0, NULL, onevalue},
74 {"UP", 2, 0, NULL, onevalue},
75 {"INDIRECT", 3, 0, NULL, intvalue},
76 {"DETAIL", 3, 0, NULL, qualvalue},
77 {"PENUMBRAS", 3, 0, NULL, boolvalue},
78 {"VARIABILITY", 3, 0, NULL, qualvalue},
79 {"REPORT", 3, 0, NULL, onevalue},
80 {"RAWSAVE", 3, 0, NULL, boolvalue},
81 };
82
83 VARIABLE *matchvar();
84 char *nvalue();
85
86 #define UPPER(c) ((c)&~0x20) /* ASCII trick */
87
88 #define vnam(vc) (vv[vc].name)
89 #define vdef(vc) (vv[vc].nass)
90 #define vval(vc) (vv[vc].value)
91 #define vint(vc) atoi(vval(vc))
92 #define vlet(vc) UPPER(vval(vc)[0])
93 #define vscale vlet
94 #define vbool(vc) (vlet(vc)=='T')
95
96 #define HIGH 'H'
97 #define MEDIUM 'M'
98 #define LOW 'L'
99
100 /* overture calculation file */
101 #ifdef NIX
102 char overfile[] = "overture.raw";
103 #else
104 char overfile[] = "/dev/null";
105 #endif
106
107 extern time_t fdate(), time();
108
109 time_t scenedate; /* date of latest scene or object file */
110 time_t octreedate; /* date of octree */
111 time_t matdate; /* date of latest material file */
112 time_t illumdate; /* date of last illum file */
113
114 char *oct0name; /* name of pre-mkillum octree */
115 time_t oct0date; /* date of pre-mkillum octree */
116 char *oct1name; /* name of post-mkillum octree */
117 time_t oct1date; /* date of post-mkillum octree (>= matdate) */
118
119 int nowarn = 0; /* no warnings */
120 int explicate = 0; /* explicate variables */
121 int silent = 0; /* do work silently */
122 int touchonly = 0; /* touch files only */
123 int noaction = 0; /* don't do anything */
124 int sayview = 0; /* print view out */
125 char *rvdevice = NULL; /* rview output device */
126 char *viewselect = NULL; /* specific view only */
127
128 int overture = 0; /* overture calculation needed */
129
130 char *progname; /* global argv[0] */
131 char *rifname; /* global rad input file name */
132
133 char radname[MAXPATH]; /* root Radiance file name */
134
135
136 main(argc, argv)
137 int argc;
138 char *argv[];
139 {
140 char ropts[512];
141 char popts[64];
142 int i;
143
144 progname = argv[0];
145 /* get options */
146 for (i = 1; i < argc && argv[i][0] == '-'; i++)
147 switch (argv[i][1]) {
148 case 's':
149 silent++;
150 break;
151 case 'n':
152 noaction++;
153 break;
154 case 't':
155 touchonly++;
156 break;
157 case 'e':
158 explicate++;
159 break;
160 case 'o':
161 rvdevice = argv[++i];
162 break;
163 case 'V':
164 sayview++;
165 break;
166 case 'v':
167 viewselect = argv[++i];
168 break;
169 case 'w':
170 nowarn++;
171 break;
172 default:
173 goto userr;
174 }
175 if (i >= argc)
176 goto userr;
177 rifname = argv[i];
178 /* assign Radiance root file name */
179 rootname(radname, rifname);
180 /* load variable values */
181 load(rifname);
182 /* get any additional assignments */
183 for (i++; i < argc; i++)
184 setvariable(argv[i]);
185 /* check assignments */
186 checkvalues();
187 /* check files and dates */
188 checkfiles();
189 /* set default values as necessary */
190 setdefaults();
191 /* print all values if requested */
192 if (explicate)
193 printvals();
194 /* build octree (and run mkillum) */
195 oconv();
196 /* check date on ambient file */
197 checkambfile();
198 /* run simulation */
199 renderopts(ropts, popts);
200 xferopts(ropts);
201 if (rvdevice != NULL)
202 rview(ropts, popts);
203 else
204 rpict(ropts, popts);
205 exit(0);
206 userr:
207 fprintf(stderr,
208 "Usage: %s [-s][-n][-t][-e][-V][-v view][-o dev] rfile [VAR=value ..]\n",
209 progname);
210 exit(1);
211 }
212
213
214 rootname(rn, fn) /* remove tail from end of fn */
215 register char *rn, *fn;
216 {
217 char *tp, *dp;
218
219 for (tp = NULL, dp = rn; *rn = *fn++; rn++)
220 if (ISDIRSEP(*rn))
221 dp = rn;
222 else if (*rn == '.')
223 tp = rn;
224 if (tp != NULL && tp > dp)
225 *tp = '\0';
226 }
227
228
229 #define NOCHAR 127 /* constant for character to delete */
230
231
232 load(rfname) /* load Radiance simulation file */
233 char *rfname;
234 {
235 FILE *fp;
236 char buf[512];
237 register char *cp;
238
239 if (rfname == NULL)
240 fp = stdin;
241 else if ((fp = fopen(rfname, "r")) == NULL)
242 syserr(rfname);
243 while (fgetline(buf, sizeof(buf), fp) != NULL) {
244 for (cp = buf; *cp; cp++) {
245 switch (*cp) {
246 case '\\':
247 *cp++ = NOCHAR;
248 continue;
249 case '#':
250 *cp = '\0';
251 break;
252 default:
253 continue;
254 }
255 break;
256 }
257 setvariable(buf);
258 }
259 fclose(fp);
260 }
261
262
263 setvariable(ass) /* assign variable according to string */
264 register char *ass;
265 {
266 char varname[32];
267 int n;
268 register char *cp;
269 register VARIABLE *vp;
270 register int i;
271
272 while (isspace(*ass)) /* skip leading space */
273 ass++;
274 cp = varname; /* extract name */
275 while (cp < varname+sizeof(varname)-1
276 && *ass && !isspace(*ass) && *ass != '=')
277 *cp++ = *ass++;
278 *cp = '\0';
279 if (!varname[0])
280 return; /* no variable name! */
281 /* trim value */
282 while (isspace(*ass) || *ass == '=')
283 ass++;
284 for (n = strlen(ass); n > 0; n--)
285 if (!isspace(ass[n-1]))
286 break;
287 if (!n && !nowarn) {
288 fprintf(stderr, "%s: warning - missing value for variable '%s'\n",
289 progname, varname);
290 return;
291 }
292 /* match variable from list */
293 vp = matchvar(varname);
294 if (vp == NULL) {
295 fprintf(stderr, "%s: unknown variable '%s'\n",
296 progname, varname);
297 exit(1);
298 }
299 /* assign new value */
300 if (i = vp->nass) {
301 cp = vp->value;
302 while (i--)
303 while (*cp++)
304 ;
305 i = cp - vp->value;
306 vp->value = realloc(vp->value, i+n+1);
307 } else
308 vp->value = malloc(n+1);
309 if (vp->value == NULL)
310 syserr(progname);
311 cp = vp->value+i; /* copy value, squeezing spaces */
312 *cp = *ass;
313 for (i = 1; i <= n; i++) {
314 if (ass[i] == NOCHAR)
315 continue;
316 if (isspace(*cp))
317 while (isspace(ass[i]))
318 i++;
319 *++cp = ass[i];
320 }
321 if (isspace(*cp)) /* remove trailing space */
322 *cp = '\0';
323 vp->nass++;
324 }
325
326
327 VARIABLE *
328 matchvar(nam) /* match a variable by its name */
329 char *nam;
330 {
331 int n = strlen(nam);
332 register int i;
333
334 for (i = 0; i < NVARS; i++)
335 if (n >= vv[i].nick && !strncmp(nam, vv[i].name, n))
336 return(vv+i);
337 return(NULL);
338 }
339
340
341 char *
342 nvalue(vp, n) /* return nth variable value */
343 VARIABLE *vp;
344 register int n;
345 {
346 register char *cp;
347
348 if (vp == NULL | n < 0 | n >= vp->nass)
349 return(NULL);
350 cp = vp->value;
351 while (n--)
352 while (*cp++)
353 ;
354 return(cp);
355 }
356
357
358 checkvalues() /* check assignments */
359 {
360 register int i;
361
362 for (i = 0; i < NVARS; i++)
363 if (vv[i].fixval != NULL)
364 (*vv[i].fixval)(vv+i);
365 }
366
367
368 onevalue(vp) /* only one assignment for this variable */
369 register VARIABLE *vp;
370 {
371 if (vp->nass < 2)
372 return;
373 if (!nowarn)
374 fprintf(stderr,
375 "%s: warning - multiple assignment of variable '%s'\n",
376 progname, vp->name);
377 do
378 vp->value += strlen(vp->value)+1;
379 while (--vp->nass > 1);
380 }
381
382
383 catvalues(vp) /* concatenate variable values */
384 register VARIABLE *vp;
385 {
386 register char *cp;
387
388 if (vp->nass < 2)
389 return;
390 for (cp = vp->value; vp->nass > 1; vp->nass--) {
391 while (*cp)
392 cp++;
393 *cp++ = ' ';
394 }
395 }
396
397
398 int
399 badmatch(tv, cv) /* case insensitive truncated comparison */
400 register char *tv, *cv;
401 {
402 if (!*tv) return(1); /* null string cannot match */
403 do
404 if (UPPER(*tv) != *cv++)
405 return(1);
406 while (*++tv);
407 return(0); /* OK */
408 }
409
410
411 boolvalue(vp) /* check boolean for legal values */
412 register VARIABLE *vp;
413 {
414 if (!vp->nass) return;
415 onevalue(vp);
416 switch (UPPER(vp->value[0])) {
417 case 'T':
418 if (badmatch(vp->value, "TRUE")) break;
419 return;
420 case 'F':
421 if (badmatch(vp->value, "FALSE")) break;
422 return;
423 }
424 fprintf(stderr, "%s: illegal value for boolean variable '%s'\n",
425 progname, vp->name);
426 exit(1);
427 }
428
429
430 qualvalue(vp) /* check qualitative var. for legal values */
431 register VARIABLE *vp;
432 {
433 if (!vp->nass) return;
434 onevalue(vp);
435 switch (UPPER(vp->value[0])) {
436 case 'L':
437 if (badmatch(vp->value, "LOW")) break;
438 return;
439 case 'M':
440 if (badmatch(vp->value, "MEDIUM")) break;
441 return;
442 case 'H':
443 if (badmatch(vp->value, "HIGH")) break;
444 return;
445 }
446 fprintf(stderr, "%s: illegal value for qualitative variable '%s'\n",
447 progname, vp->name);
448 exit(1);
449 }
450
451
452 intvalue(vp) /* check integer variable for legal values */
453 register VARIABLE *vp;
454 {
455 if (!vp->nass) return;
456 onevalue(vp);
457 if (isint(vp->value)) return;
458 fprintf(stderr, "%s: illegal value for integer variable '%s'\n",
459 progname, vp->name);
460 exit(1);
461 }
462
463
464 fltvalue(vp) /* check float variable for legal values */
465 register VARIABLE *vp;
466 {
467 if (!vp->nass) return;
468 onevalue(vp);
469 if (isflt(vp->value)) return;
470 fprintf(stderr, "%s: illegal value for real variable '%s'\n",
471 progname, vp->name);
472 exit(1);
473 }
474
475
476 time_t
477 checklast(fnames) /* check files and find most recent */
478 register char *fnames;
479 {
480 char thisfile[MAXPATH];
481 time_t thisdate, lastdate = 0;
482 register char *cp;
483
484 if (fnames == NULL)
485 return(0);
486 while (*fnames) {
487 while (isspace(*fnames)) fnames++;
488 cp = thisfile;
489 while (*fnames && !isspace(*fnames))
490 *cp++ = *fnames++;
491 *cp = '\0';
492 if (!(thisdate = fdate(thisfile)))
493 syserr(thisfile);
494 if (thisdate > lastdate)
495 lastdate = thisdate;
496 }
497 return(lastdate);
498 }
499
500
501 char *
502 newfname(orig, pred) /* create modified file name */
503 char *orig;
504 int pred;
505 {
506 extern char *rindex();
507 register char *cp;
508 register int n;
509 int suffix;
510
511 n = 0; cp = orig; suffix = -1; /* suffix position, length */
512 while (*cp) {
513 if (*cp == '.') suffix = n;
514 else if (ISDIRSEP(*cp)) suffix = -1;
515 cp++; n++;
516 }
517 if (suffix == -1) suffix = n;
518 if ((cp = bmalloc(n+2)) == NULL)
519 syserr(progname);
520 strncpy(cp, orig, suffix);
521 cp[suffix] = pred; /* root name + pred + suffix */
522 strcpy(cp+suffix+1, orig+suffix);
523 return(cp);
524 }
525
526
527 checkfiles() /* check for existence and modified times */
528 {
529 time_t objdate;
530
531 if (!vdef(OCTREE)) {
532 if ((vval(OCTREE) = bmalloc(strlen(radname)+5)) == NULL)
533 syserr(progname);
534 sprintf(vval(OCTREE), "%s.oct", radname);
535 vdef(OCTREE)++;
536 }
537 octreedate = fdate(vval(OCTREE));
538 if (vdef(ILLUM)) { /* illum requires secondary octrees */
539 oct0name = newfname(vval(OCTREE), '0');
540 oct1name = newfname(vval(OCTREE), '1');
541 oct0date = fdate(oct0name);
542 oct1date = fdate(oct1name);
543 } else
544 oct0name = oct1name = vval(OCTREE);
545 if ((scenedate = checklast(vval(SCENE))) &&
546 (objdate = checklast(vval(OBJECT))) > scenedate)
547 scenedate = objdate;
548 illumdate = checklast(vval(ILLUM));
549 if (!octreedate & !scenedate & !illumdate) {
550 fprintf(stderr, "%s: need '%s' or '%s' or '%s'\n", progname,
551 vnam(OCTREE), vnam(SCENE), vnam(ILLUM));
552 exit(1);
553 }
554 matdate = checklast(vval(MATERIAL));
555 }
556
557
558 getoctcube(org, sizp) /* get octree bounding cube */
559 double org[3], *sizp;
560 {
561 extern FILE *popen();
562 static double oorg[3], osiz = 0.;
563 double min[3], max[3];
564 char buf[512];
565 FILE *fp;
566 register int i;
567
568 if (osiz <= FTINY)
569 if (noaction && fdate(oct1name) <
570 (scenedate>illumdate?scenedate:illumdate)) {
571 /* run getbbox */
572 sprintf(buf, "getbbox -w -h %s",
573 vdef(SCENE) ? vval(SCENE) : vval(ILLUM));
574 if ((fp = popen(buf, "r")) == NULL)
575 syserr("getbbox");
576 if (fscanf(fp, "%lf %lf %lf %lf %lf %lf",
577 &min[0], &max[0], &min[1], &max[1],
578 &min[2], &max[2]) != 6) {
579 fprintf(stderr,
580 "%s: error reading bounding box from getbbox\n",
581 progname);
582 exit(1);
583 }
584 for (i = 0; i < 3; i++)
585 if (max[i] - min[i] > osiz)
586 osiz = max[i] - min[i];
587 for (i = 0; i < 3; i++)
588 oorg[i] = (max[i]+min[i]-osiz)*.5;
589 pclose(fp);
590 } else { /* from octree */
591 oconv(); /* does nothing if done already */
592 sprintf(buf, "getinfo -d < %s", oct1name);
593 if ((fp = popen(buf, "r")) == NULL)
594 syserr("getinfo");
595 if (fscanf(fp, "%lf %lf %lf %lf", &oorg[0], &oorg[1],
596 &oorg[2], &osiz) != 4) {
597 fprintf(stderr,
598 "%s: error reading bounding cube from getinfo\n",
599 progname);
600 exit(1);
601 }
602 pclose(fp);
603 }
604 org[0] = oorg[0]; org[1] = oorg[1]; org[2] = oorg[2]; *sizp = osiz;
605 }
606
607
608 setdefaults() /* set default values for unassigned var's */
609 {
610 double org[3], size;
611 char buf[128];
612
613 if (!vdef(ZONE)) {
614 getoctcube(org, &size);
615 sprintf(buf, "E %g %g %g %g %g %g", org[0], org[0]+size,
616 org[1], org[1]+size, org[2], org[2]+size);
617 vval(ZONE) = savqstr(buf);
618 vdef(ZONE)++;
619 }
620 if (!vdef(INDIRECT)) {
621 vval(INDIRECT) = "0";
622 vdef(INDIRECT)++;
623 }
624 if (!vdef(QUALITY)) {
625 vval(QUALITY) = "L";
626 vdef(QUALITY)++;
627 }
628 if (!vdef(RESOLUTION)) {
629 vval(RESOLUTION) = "512";
630 vdef(RESOLUTION)++;
631 }
632 if (!vdef(PICTURE)) {
633 vval(PICTURE) = radname;
634 vdef(PICTURE)++;
635 }
636 if (!vdef(VIEW)) {
637 vval(VIEW) = "X";
638 vdef(VIEW)++;
639 }
640 if (!vdef(DETAIL)) {
641 vval(DETAIL) = "M";
642 vdef(DETAIL)++;
643 }
644 if (!vdef(PENUMBRAS)) {
645 vval(PENUMBRAS) = "F";
646 vdef(PENUMBRAS)++;
647 }
648 if (!vdef(VARIABILITY)) {
649 vval(VARIABILITY) = "L";
650 vdef(VARIABILITY)++;
651 }
652 if (!vdef(RAWSAVE)) {
653 vval(RAWSAVE) = "F";
654 vdef(RAWSAVE)++;
655 }
656 }
657
658
659 printvals() /* print variable values */
660 {
661 int i, j, clipline;
662 register char *cp;
663 register int k;
664
665 for (i = 0; i < NVARS; i++) /* print each variable */
666 for (j = 0; j < vdef(i); j++) { /* print each assignment */
667 fputs(vnam(i), stdout);
668 fputs("= ", stdout);
669 k = clipline = ( vv[i].fixval == catvalues ? 64 : 320 )
670 - strlen(vnam(i)) ;
671 cp = nvalue(vv+i, j);
672 while (*cp) {
673 putchar(*cp++);
674 if (--k <= 0) { /* line too long */
675 while (*cp && !isspace(*cp))
676 putchar(*cp++); /* finish this word */
677 if (*cp) { /* start new line */
678 putchar('\n');
679 fputs(vnam(i), stdout);
680 putchar('=');
681 k = clipline;
682 }
683 }
684 }
685 putchar('\n');
686 }
687 fflush(stdout);
688 }
689
690
691 oconv() /* run oconv and mkillum if necessary */
692 {
693 static char illumtmp[] = "ilXXXXXX";
694 char combuf[512], ocopts[64], mkopts[64];
695
696 oconvopts(ocopts); /* get options */
697 if (octreedate < scenedate) { /* check date on original octree */
698 if (touchonly && octreedate)
699 touch(vval(OCTREE));
700 else { /* build command */
701 if (vdef(MATERIAL))
702 sprintf(combuf, "oconv%s %s %s > %s", ocopts,
703 vval(MATERIAL), vval(SCENE),
704 vval(OCTREE));
705 else
706 sprintf(combuf, "oconv%s %s > %s", ocopts,
707 vval(SCENE), vval(OCTREE));
708
709 if (runcom(combuf)) { /* run it */
710 fprintf(stderr,
711 "%s: error generating octree\n\t%s removed\n",
712 progname, vval(OCTREE));
713 unlink(vval(OCTREE));
714 exit(1);
715 }
716 }
717 octreedate = time((time_t *)NULL);
718 if (octreedate < scenedate) /* in case clock is off */
719 octreedate = scenedate;
720 }
721 if (oct1name == vval(OCTREE)) /* no mkillum? */
722 oct1date = octreedate > matdate ? octreedate : matdate;
723 if (oct1date >= octreedate & oct1date >= matdate
724 & oct1date >= illumdate) /* all done */
725 return;
726 /* make octree0 */
727 if (oct0date < scenedate | oct0date < illumdate) {
728 if (touchonly && oct0date)
729 touch(oct0name);
730 else { /* build command */
731 if (octreedate)
732 sprintf(combuf, "oconv%s -i %s %s > %s", ocopts,
733 vval(OCTREE), vval(ILLUM), oct0name);
734 else if (vdef(MATERIAL))
735 sprintf(combuf, "oconv%s %s %s > %s", ocopts,
736 vval(MATERIAL), vval(ILLUM), oct0name);
737 else
738 sprintf(combuf, "oconv%s %s > %s", ocopts,
739 vval(ILLUM), oct0name);
740 if (runcom(combuf)) { /* run it */
741 fprintf(stderr,
742 "%s: error generating octree\n\t%s removed\n",
743 progname, oct0name);
744 unlink(oct0name);
745 exit(1);
746 }
747 }
748 oct0date = time((time_t *)NULL);
749 if (oct0date < octreedate) /* in case clock is off */
750 oct0date = octreedate;
751 if (oct0date < illumdate) /* ditto */
752 oct0date = illumdate;
753 }
754 if (touchonly && oct1date)
755 touch(oct1name);
756 else {
757 mkillumopts(mkopts); /* build mkillum command */
758 mktemp(illumtmp);
759 sprintf(combuf, "mkillum%s %s \"<\" %s > %s", mkopts,
760 oct0name, vval(ILLUM), illumtmp);
761 if (runcom(combuf)) { /* run it */
762 fprintf(stderr, "%s: error running mkillum\n",
763 progname);
764 unlink(illumtmp);
765 exit(1);
766 }
767 /* make octree1 (frozen) */
768 if (octreedate)
769 sprintf(combuf, "oconv%s -f -i %s %s > %s", ocopts,
770 vval(OCTREE), illumtmp, oct1name);
771 else if (vdef(MATERIAL))
772 sprintf(combuf, "oconv%s -f %s %s > %s", ocopts,
773 vval(MATERIAL), illumtmp, oct1name);
774 else
775 sprintf(combuf, "oconv%s -f %s > %s", ocopts,
776 illumtmp, oct1name);
777 if (runcom(combuf)) { /* run it */
778 fprintf(stderr,
779 "%s: error generating octree\n\t%s removed\n",
780 progname, oct1name);
781 unlink(oct1name);
782 exit(1);
783 }
784 rmfile(illumtmp);
785 }
786 oct1date = time((time_t *)NULL);
787 if (oct1date < oct0date) /* in case clock is off */
788 oct1date = oct0date;
789 }
790
791
792 char *
793 addarg(op, arg) /* add argument and advance pointer */
794 register char *op, *arg;
795 {
796 *op = ' ';
797 while (*++op = *arg++)
798 ;
799 return(op);
800 }
801
802
803 oconvopts(oo) /* get oconv options */
804 register char *oo;
805 {
806 /* BEWARE: This may be called via setdefaults(), so no assumptions */
807
808 *oo = '\0';
809 if (vdef(OCONV))
810 addarg(oo, vval(OCONV));
811 }
812
813
814 mkillumopts(mo) /* get mkillum options */
815 register char *mo;
816 {
817 /* BEWARE: This may be called via setdefaults(), so no assumptions */
818
819 *mo = '\0';
820 if (vdef(MKILLUM))
821 addarg(mo, vval(MKILLUM));
822 }
823
824
825 checkambfile() /* check date on ambient file */
826 {
827 time_t afdate;
828
829 if (!vdef(AMBFILE))
830 return;
831 if (!(afdate = fdate(vval(AMBFILE))))
832 return;
833 if (oct1date > afdate)
834 if (touchonly)
835 touch(vval(AMBFILE));
836 else
837 rmfile(vval(AMBFILE));
838 }
839
840
841 double
842 ambval() /* compute ambient value */
843 {
844 if (vdef(EXPOSURE)) {
845 if (vval(EXPOSURE)[0] == '+' || vval(EXPOSURE)[0] == '-')
846 return(.5/pow(2.,atof(vval(EXPOSURE))));
847 return(.5/atof(vval(EXPOSURE)));
848 }
849 if (vlet(ZONE) == 'E')
850 return(10.);
851 if (vlet(ZONE) == 'I')
852 return(.01);
853 badvalue(ZONE);
854 }
855
856
857 renderopts(op, po) /* set rendering options */
858 char *op, *po;
859 {
860 switch(vscale(QUALITY)) {
861 case LOW:
862 lowqopts(op, po);
863 break;
864 case MEDIUM:
865 medqopts(op, po);
866 break;
867 case HIGH:
868 hiqopts(op, po);
869 break;
870 }
871 }
872
873
874 lowqopts(op, po) /* low quality rendering options */
875 register char *op;
876 char *po;
877 {
878 double d, org[3], siz[3];
879
880 *op = '\0';
881 *po = '\0';
882 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
883 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
884 badvalue(ZONE);
885 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
886 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
887 badvalue(ZONE);
888 getoctcube(org, &d);
889 d *= 3./(siz[0]+siz[1]+siz[2]);
890 switch (vscale(DETAIL)) {
891 case LOW:
892 po = addarg(po, "-ps 16");
893 op = addarg(op, "-dp 64");
894 sprintf(op, " -ar %d", (int)(4*d));
895 op += strlen(op);
896 break;
897 case MEDIUM:
898 po = addarg(po, "-ps 8");
899 op = addarg(op, "-dp 128");
900 sprintf(op, " -ar %d", (int)(8*d));
901 op += strlen(op);
902 break;
903 case HIGH:
904 po = addarg(po, "-ps 4");
905 op = addarg(op, "-dp 256");
906 sprintf(op, " -ar %d", (int)(16*d));
907 op += strlen(op);
908 break;
909 }
910 po = addarg(po, "-pt .16");
911 if (vbool(PENUMBRAS))
912 op = addarg(op, "-ds .4");
913 else
914 op = addarg(op, "-ds 0");
915 op = addarg(op, "-dt .2 -dc .25 -dr 0 -sj 0 -st .5");
916 if (vdef(AMBFILE)) {
917 sprintf(op, " -af %s", vval(AMBFILE));
918 op += strlen(op);
919 } else
920 overture = 0;
921 switch (vscale(VARIABILITY)) {
922 case LOW:
923 op = addarg(op, "-aa .4 -ad 64");
924 break;
925 case MEDIUM:
926 op = addarg(op, "-aa .3 -ad 128");
927 break;
928 case HIGH:
929 op = addarg(op, "-aa .25 -ad 256");
930 break;
931 }
932 op = addarg(op, "-as 0");
933 d = ambval();
934 sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
935 op += strlen(op);
936 op = addarg(op, "-lr 3 -lw .02");
937 if (vdef(RENDER))
938 op = addarg(op, vval(RENDER));
939 }
940
941
942 medqopts(op, po) /* medium quality rendering options */
943 register char *op;
944 char *po;
945 {
946 double d, org[3], siz[3];
947
948 *op = '\0';
949 *po = '\0';
950 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
951 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
952 badvalue(ZONE);
953 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
954 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
955 badvalue(ZONE);
956 getoctcube(org, &d);
957 d *= 3./(siz[0]+siz[1]+siz[2]);
958 switch (vscale(DETAIL)) {
959 case LOW:
960 po = addarg(po, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8");
961 op = addarg(op, "-dp 256");
962 sprintf(op, " -ar %d", (int)(8*d));
963 op += strlen(op);
964 break;
965 case MEDIUM:
966 po = addarg(po, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6");
967 op = addarg(op, "-dp 512");
968 sprintf(op, " -ar %d", (int)(16*d));
969 op += strlen(op);
970 break;
971 case HIGH:
972 po = addarg(po, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4");
973 op = addarg(op, "-dp 1024");
974 sprintf(op, " -ar %d", (int)(32*d));
975 op += strlen(op);
976 break;
977 }
978 po = addarg(po, "-pt .08");
979 if (vbool(PENUMBRAS))
980 op = addarg(op, "-ds .2 -dj .5");
981 else
982 op = addarg(op, "-ds .3");
983 op = addarg(op, "-dt .1 -dc .5 -dr 1 -sj .7 -st .1");
984 if (overture = vint(INDIRECT)) {
985 sprintf(op, " -ab %d", overture);
986 op += strlen(op);
987 }
988 if (vdef(AMBFILE)) {
989 sprintf(op, " -af %s", vval(AMBFILE));
990 op += strlen(op);
991 } else
992 overture = 0;
993 switch (vscale(VARIABILITY)) {
994 case LOW:
995 op = addarg(op, "-aa .25 -ad 196 -as 0");
996 break;
997 case MEDIUM:
998 op = addarg(op, "-aa .2 -ad 400 -as 64");
999 break;
1000 case HIGH:
1001 op = addarg(op, "-aa .15 -ad 768 -as 196");
1002 break;
1003 }
1004 d = ambval();
1005 sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
1006 op += strlen(op);
1007 op = addarg(op, "-lr 6 -lw .002");
1008 if (vdef(RENDER))
1009 op = addarg(op, vval(RENDER));
1010 }
1011
1012
1013 hiqopts(op, po) /* high quality rendering options */
1014 register char *op;
1015 char *po;
1016 {
1017 double d, org[3], siz[3];
1018
1019 *op = '\0';
1020 *po = '\0';
1021 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
1022 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
1023 badvalue(ZONE);
1024 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
1025 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
1026 badvalue(ZONE);
1027 getoctcube(org, &d);
1028 d *= 3./(siz[0]+siz[1]+siz[2]);
1029 switch (vscale(DETAIL)) {
1030 case LOW:
1031 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8");
1032 op = addarg(op, "-dp 1024");
1033 sprintf(op, " -ar %d", (int)(16*d));
1034 op += strlen(op);
1035 break;
1036 case MEDIUM:
1037 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5");
1038 op = addarg(op, "-dp 2048");
1039 sprintf(op, " -ar %d", (int)(32*d));
1040 op += strlen(op);
1041 break;
1042 case HIGH:
1043 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3");
1044 op = addarg(op, "-dp 4096");
1045 sprintf(op, " -ar %d", (int)(64*d));
1046 op += strlen(op);
1047 break;
1048 }
1049 po = addarg(po, "-pt .04");
1050 if (vbool(PENUMBRAS))
1051 op = addarg(op, "-ds .1 -dj .65");
1052 else
1053 op = addarg(op, "-ds .2");
1054 op = addarg(op, "-dt .05 -dc .75 -dr 3 -sj 1 -st .01");
1055 sprintf(op, " -ab %d", overture=vint(INDIRECT)+1);
1056 op += strlen(op);
1057 if (vdef(AMBFILE)) {
1058 sprintf(op, " -af %s", vval(AMBFILE));
1059 op += strlen(op);
1060 } else
1061 overture = 0;
1062 switch (vscale(VARIABILITY)) {
1063 case LOW:
1064 op = addarg(op, "-aa .15 -ad 256 -as 0");
1065 break;
1066 case MEDIUM:
1067 op = addarg(op, "-aa .125 -ad 512 -as 256");
1068 break;
1069 case HIGH:
1070 op = addarg(op, "-aa .08 -ad 1024 -as 512");
1071 break;
1072 }
1073 d = ambval();
1074 sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
1075 op += strlen(op);
1076 op = addarg(op, "-lr 12 -lw .0005");
1077 if (vdef(RENDER))
1078 op = addarg(op, vval(RENDER));
1079 }
1080
1081
1082 xferopts(ro) /* transfer options if indicated */
1083 char *ro;
1084 {
1085 int fd, n;
1086 register char *cp;
1087
1088 n = strlen(ro);
1089 if (n < 2)
1090 return;
1091 if (vdef(OPTFILE)) {
1092 for (cp = ro; cp[1]; cp++)
1093 if (isspace(cp[1]) && cp[2] == '-' && isalpha(cp[3]))
1094 *cp = '\n';
1095 else
1096 *cp = cp[1];
1097 *cp = '\n';
1098 fd = open(vval(OPTFILE), O_WRONLY|O_CREAT|O_TRUNC, 0666);
1099 if (fd < 0 || write(fd, ro, n) != n || close(fd) < 0)
1100 syserr(vval(OPTFILE));
1101 sprintf(ro, " @%s", vval(OPTFILE));
1102 }
1103 #ifdef MSDOS
1104 else if (n > 50) {
1105 setenv("ROPT", ro+1);
1106 strcpy(ro, " $ROPT");
1107 }
1108 #endif
1109 }
1110
1111
1112 pfiltopts(po) /* get pfilt options */
1113 register char *po;
1114 {
1115 *po = '\0';
1116 if (vdef(EXPOSURE)) {
1117 po = addarg(po, "-1 -e");
1118 po = addarg(po, vval(EXPOSURE));
1119 }
1120 switch (vscale(QUALITY)) {
1121 case MEDIUM:
1122 po = addarg(po, "-r 1");
1123 break;
1124 case HIGH:
1125 po = addarg(po, "-m .25");
1126 break;
1127 }
1128 if (vdef(PFILT))
1129 po = addarg(po, vval(PFILT));
1130 }
1131
1132
1133 matchword(s1, s2) /* match white-delimited words */
1134 register char *s1, *s2;
1135 {
1136 while (isspace(*s1)) s1++;
1137 while (isspace(*s2)) s2++;
1138 while (*s1 && !isspace(*s1))
1139 if (*s1++ != *s2++)
1140 return(0);
1141 return(!*s2 || isspace(*s2));
1142 }
1143
1144
1145 char *
1146 specview(vs) /* get proper view spec from vs */
1147 register char *vs;
1148 {
1149 static char vup[7][12] = {"-vu 0 0 -1","-vu 0 -1 0","-vu -1 0 0",
1150 "-vu 0 0 1", "-vu 1 0 0","-vu 0 1 0","-vu 0 0 1"};
1151 static char viewopts[128];
1152 register char *cp;
1153 int xpos, ypos, zpos, viewtype, upax;
1154 register int i;
1155 double cent[3], dim[3], mult, d;
1156
1157 if (vs == NULL || *vs == '-')
1158 return(vs);
1159 upax = 0; /* get the up vector */
1160 if (vdef(UP)) {
1161 if (vval(UP)[0] == '-' || vval(UP)[0] == '+')
1162 upax = 1-'X'+UPPER(vval(UP)[1]);
1163 else
1164 upax = 1-'X'+vlet(UP);
1165 if (upax < 1 | upax > 3)
1166 badvalue(UP);
1167 if (vval(UP)[0] == '-')
1168 upax = -upax;
1169 }
1170 /* check standard view names */
1171 xpos = ypos = zpos = 0;
1172 if (*vs == 'X') {
1173 xpos = 1; vs++;
1174 } else if (*vs == 'x') {
1175 xpos = -1; vs++;
1176 }
1177 if (*vs == 'Y') {
1178 ypos = 1; vs++;
1179 } else if (*vs == 'y') {
1180 ypos = -1; vs++;
1181 }
1182 if (*vs == 'Z') {
1183 zpos = 1; vs++;
1184 } else if (*vs == 'z') {
1185 zpos = -1; vs++;
1186 }
1187 viewtype = 'v';
1188 if (*vs == 'v' | *vs == 'l' | *vs == 'a' | *vs == 'h' | *vs == 'c')
1189 viewtype = *vs++;
1190 cp = viewopts;
1191 if ((!*vs || isspace(*vs)) && (xpos|ypos|zpos)) { /* got one! */
1192 *cp++ = '-'; *cp++ = 'v'; *cp++ = 't'; *cp++ = viewtype;
1193 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf",
1194 &cent[0], &dim[0], &cent[1], &dim[1],
1195 &cent[2], &dim[2]) != 6)
1196 badvalue(ZONE);
1197 for (i = 0; i < 3; i++) {
1198 dim[i] -= cent[i];
1199 if (dim[i] <= FTINY)
1200 badvalue(ZONE);
1201 cent[i] += .5*dim[i];
1202 }
1203 mult = vlet(ZONE)=='E' ? 2. : .45 ;
1204 sprintf(cp, " -vp %.2g %.2g %.2g -vd %.2g %.2g %.2g",
1205 cent[0]+xpos*mult*dim[0],
1206 cent[1]+ypos*mult*dim[1],
1207 cent[2]+zpos*mult*dim[2],
1208 -xpos*dim[0], -ypos*dim[1], -zpos*dim[2]);
1209 cp += strlen(cp);
1210 /* redirect up axis if necessary */
1211 switch (upax) {
1212 case 3: /* plus or minus Z axis */
1213 case -3:
1214 case 0:
1215 if (!(xpos|ypos))
1216 upax = 2;
1217 break;
1218 case 2: /* plus or minus Y axis */
1219 case -2:
1220 if (!(xpos|zpos))
1221 upax = 1;
1222 break;
1223 case 1: /* plus or minus X axis */
1224 case -1:
1225 if (!(ypos|zpos))
1226 upax = 3;
1227 break;
1228 }
1229 cp = addarg(cp, vup[upax+3]);
1230 switch (viewtype) {
1231 case 'v':
1232 cp = addarg(cp, "-vh 45 -vv 45");
1233 break;
1234 case 'l':
1235 d = sqrt(dim[0]*dim[0]+dim[1]*dim[1]+dim[2]*dim[2]);
1236 sprintf(cp, " -vh %.2g -vv %.2g", d, d);
1237 cp += strlen(cp);
1238 break;
1239 case 'a':
1240 case 'h':
1241 cp = addarg(cp, "-vh 180 -vv 180");
1242 break;
1243 case 'c':
1244 cp = addarg(cp, "-vh 180 -vv 90");
1245 break;
1246 }
1247 } else {
1248 while (!isspace(*vs)) /* else skip id */
1249 if (!*vs++)
1250 return(NULL);
1251 if (upax) { /* specify up vector */
1252 strcpy(cp, vup[upax+3]);
1253 cp += strlen(cp);
1254 }
1255 }
1256 if (cp == viewopts) /* append any additional options */
1257 vs++; /* skip prefixed space if unneeded */
1258 strcpy(cp, vs);
1259 #ifdef MSDOS
1260 if (strlen(viewopts) > 40) {
1261 setenv("VIEW", viewopts);
1262 return("$VIEW");
1263 }
1264 #endif
1265 return(viewopts);
1266 }
1267
1268
1269 char *
1270 getview(n, vn) /* get view n, or NULL if none */
1271 int n;
1272 char *vn; /* returned view name */
1273 {
1274 register char *mv;
1275
1276 if (viewselect != NULL) { /* command-line selected */
1277 if (n) /* only do one */
1278 return(NULL);
1279 if (viewselect[0] == '-') { /* already specified */
1280 if (vn != NULL) *vn = '\0';
1281 return(viewselect);
1282 }
1283 if (vn != NULL) {
1284 for (mv = viewselect; *mv && !isspace(*mv);
1285 *vn++ = *mv++)
1286 ;
1287 *vn = '\0';
1288 }
1289 /* view number? */
1290 if (isint(viewselect))
1291 return(specview(nvalue(vv+VIEW, atoi(viewselect)-1)));
1292 /* check list */
1293 while ((mv = nvalue(vv+VIEW, n++)) != NULL)
1294 if (matchword(viewselect, mv))
1295 return(specview(mv));
1296 return(specview(viewselect)); /* standard view? */
1297 }
1298 mv = nvalue(vv+VIEW, n); /* use view n */
1299 if (vn != NULL & mv != NULL) {
1300 register char *mv2 = mv;
1301 if (*mv2 != '-')
1302 while (*mv2 && !isspace(*mv2))
1303 *vn++ = *mv2++;
1304 *vn = '\0';
1305 }
1306 return(specview(mv));
1307 }
1308
1309
1310 printview(vopts) /* print out selected view */
1311 register char *vopts;
1312 {
1313 extern char *atos(), *getenv();
1314 char buf[256];
1315 FILE *fp;
1316 register char *cp;
1317
1318 if (vopts == NULL)
1319 return(-1);
1320 fputs("VIEW=", stdout);
1321 do {
1322 if (matchword(vopts, "-vf")) { /* expand view file */
1323 vopts = sskip(vopts);
1324 if (!*atos(buf, sizeof(buf), vopts))
1325 return(-1);
1326 if ((fp = fopen(buf, "r")) == NULL)
1327 return(-1);
1328 for (buf[sizeof(buf)-2] = '\n';
1329 fgets(buf, sizeof(buf), fp) != NULL &&
1330 buf[0] != '\n';
1331 buf[sizeof(buf)-2] = '\n') {
1332 if (buf[sizeof(buf)-2] != '\n') {
1333 ungetc(buf[sizeof(buf)-2], fp);
1334 buf[sizeof(buf)-2] = '\0';
1335 }
1336 if (matchword(buf, "VIEW=") ||
1337 matchword(buf, "rview")) {
1338 for (cp = sskip(buf); *cp && *cp != '\n'; cp++)
1339 putchar(*cp);
1340 }
1341 }
1342 fclose(fp);
1343 vopts = sskip(vopts);
1344 } else {
1345 while (isspace(*vopts))
1346 vopts++;
1347 putchar(' ');
1348 #ifdef MSDOS
1349 if (*vopts == '$') { /* expand env. var. */
1350 if (!*atos(buf, sizeof(buf), vopts+1))
1351 return(-1);
1352 if ((cp = getenv(buf)) == NULL)
1353 return(-1);
1354 fputs(cp, stdout);
1355 vopts = sskip(vopts);
1356 } else
1357 #endif
1358 while (*vopts && !isspace(*vopts))
1359 putchar(*vopts++);
1360 }
1361 } while (*vopts++);
1362 putchar('\n');
1363 return(0);
1364 }
1365
1366
1367 rview(opts, po) /* run rview with first view */
1368 char *opts, *po;
1369 {
1370 char *vw;
1371 char combuf[512];
1372 /* build command */
1373 if (touchonly || (vw = getview(0, NULL)) == NULL)
1374 return;
1375 if (sayview)
1376 printview(vw);
1377 sprintf(combuf, "rview %s%s%s -R %s ", vw, po, opts, rifname);
1378 if (rvdevice != NULL)
1379 sprintf(combuf+strlen(combuf), "-o %s ", rvdevice);
1380 if (vdef(EXPOSURE))
1381 sprintf(combuf+strlen(combuf), "-pe %s ", vval(EXPOSURE));
1382 strcat(combuf, oct1name);
1383 if (runcom(combuf)) { /* run it */
1384 fprintf(stderr, "%s: error running rview\n", progname);
1385 exit(1);
1386 }
1387 }
1388
1389
1390 rpict(opts, po) /* run rpict and pfilt for each view */
1391 char *opts, *po;
1392 {
1393 char combuf[1024];
1394 char rawfile[MAXPATH], picfile[MAXPATH], rep[MAXPATH+16], res[32];
1395 char pfopts[128];
1396 char vs[32], *vw;
1397 int vn, mult;
1398 time_t rfdt, pfdt;
1399 /* get pfilt options */
1400 pfiltopts(pfopts);
1401 /* get resolution, reporting */
1402 switch (vscale(QUALITY)) {
1403 case LOW:
1404 mult = 1;
1405 break;
1406 case MEDIUM:
1407 mult = 2;
1408 break;
1409 case HIGH:
1410 mult = 3;
1411 break;
1412 }
1413 {
1414 int xres, yres;
1415 double aspect;
1416 int n;
1417 n = sscanf(vval(RESOLUTION), "%d %d %lf", &xres, &yres, &aspect);
1418 if (n == 3)
1419 sprintf(res, "-x %d -y %d -pa %.3f",
1420 mult*xres, mult*yres, aspect);
1421 else if (n) {
1422 if (n == 1) yres = xres;
1423 sprintf(res, "-x %d -y %d", mult*xres, mult*yres);
1424 } else
1425 badvalue(RESOLUTION);
1426 }
1427 rep[0] = '\0';
1428 if (vdef(REPORT)) {
1429 double minutes;
1430 int n;
1431 n = sscanf(vval(REPORT), "%lf %s", &minutes, rawfile);
1432 if (n == 2)
1433 sprintf(rep, " -t %d -e %s", (int)(minutes*60), rawfile);
1434 else if (n == 1)
1435 sprintf(rep, " -t %d", (int)(minutes*60));
1436 else
1437 badvalue(REPORT);
1438 }
1439 /* do each view */
1440 vn = 0;
1441 while ((vw = getview(vn++, vs)) != NULL) {
1442 if (sayview)
1443 printview(vw);
1444 if (!vs[0])
1445 sprintf(vs, "%d", vn);
1446 sprintf(picfile, "%s_%s.pic", vval(PICTURE), vs);
1447 /* check date on picture */
1448 pfdt = fdate(picfile);
1449 if (pfdt >= oct1date)
1450 continue;
1451 /* get raw file name */
1452 sprintf(rawfile, "%s_%s.raw", vval(PICTURE), vs);
1453 rfdt = fdate(rawfile);
1454 if (touchonly) { /* update times only */
1455 if (rfdt) {
1456 if (rfdt < oct1date)
1457 touch(rawfile);
1458 } else if (pfdt && pfdt < oct1date)
1459 touch(picfile);
1460 continue;
1461 }
1462 /* build rpict command */
1463 if (rfdt >= oct1date) /* recover */
1464 sprintf(combuf, "rpict%s%s%s -ro %s %s",
1465 rep, po, opts, rawfile, oct1name);
1466 else {
1467 if (overture) { /* run overture calculation */
1468 sprintf(combuf,
1469 "rpict%s %s%s -x 64 -y 64 -ps 1 %s > %s",
1470 rep, vw, opts,
1471 oct1name, overfile);
1472 if (runcom(combuf)) {
1473 fprintf(stderr,
1474 "%s: error in overture for view %s\n",
1475 progname, vs);
1476 exit(1);
1477 }
1478 #ifdef NIX
1479 rmfile(overfile);
1480 #endif
1481 }
1482 sprintf(combuf, "rpict%s %s %s%s%s %s > %s",
1483 rep, vw, res, po, opts,
1484 oct1name, rawfile);
1485 }
1486 if (runcom(combuf)) { /* run rpict */
1487 fprintf(stderr, "%s: error rendering view %s\n",
1488 progname, vs);
1489 exit(1);
1490 }
1491 /* build pfilt command */
1492 if (mult > 1)
1493 sprintf(combuf, "pfilt%s -x /%d -y /%d %s > %s",
1494 pfopts, mult, mult, rawfile, picfile);
1495 else
1496 sprintf(combuf, "pfilt%s %s > %s", pfopts,
1497 rawfile, picfile);
1498 if (runcom(combuf)) { /* run pfilt */
1499 fprintf(stderr,
1500 "%s: error filtering view %s\n\t%s removed\n",
1501 progname, vs, picfile);
1502 unlink(picfile);
1503 exit(1);
1504 }
1505 /* remove/rename raw file */
1506 if (vbool(RAWSAVE)) {
1507 sprintf(combuf, "%s_%s.rwp", vval(PICTURE), vs);
1508 mvfile(rawfile, combuf);
1509 } else
1510 rmfile(rawfile);
1511 }
1512 }
1513
1514
1515 touch(fn) /* update a file */
1516 char *fn;
1517 {
1518 if (!silent)
1519 printf("\ttouch %s\n", fn);
1520 if (noaction)
1521 return(0);
1522 #ifdef notused
1523 if (access(fn, F_OK) == -1) /* create it */
1524 if (close(open(fn, O_WRONLY|O_CREAT, 0666)) == -1)
1525 return(-1);
1526 #endif
1527 return(setfdate(fn, time((time_t *)NULL)));
1528 }
1529
1530
1531 runcom(cs) /* run command */
1532 char *cs;
1533 {
1534 if (!silent) /* echo it */
1535 printf("\t%s\n", cs);
1536 if (noaction)
1537 return(0);
1538 fflush(stdout); /* flush output and pass to shell */
1539 return(system(cs));
1540 }
1541
1542
1543 rmfile(fn) /* remove a file */
1544 char *fn;
1545 {
1546 if (!silent)
1547 #ifdef MSDOS
1548 printf("\tdel %s\n", fn);
1549 #else
1550 printf("\trm -f %s\n", fn);
1551 #endif
1552 if (noaction)
1553 return(0);
1554 return(unlink(fn));
1555 }
1556
1557
1558 mvfile(fold, fnew) /* move a file */
1559 char *fold, *fnew;
1560 {
1561 if (!silent)
1562 #ifdef MSDOS
1563 printf("\trename %s %s\n", fold, fnew);
1564 #else
1565 printf("\tmv %s %s\n", fold, fnew);
1566 #endif
1567 if (noaction)
1568 return(0);
1569 return(rename(fold, fnew));
1570 }
1571
1572
1573 #ifdef MSDOS
1574 setenv(vname, value) /* set an environment variable */
1575 char *vname, *value;
1576 {
1577 register char *evp;
1578
1579 evp = bmalloc(strlen(vname)+strlen(value)+2);
1580 if (evp == NULL)
1581 syserr(progname);
1582 sprintf(evp, "%s=%s", vname, value);
1583 if (putenv(evp) != 0) {
1584 fprintf(stderr, "%s: out of environment space\n", progname);
1585 exit(1);
1586 }
1587 if (!silent)
1588 printf("set %s\n", evp);
1589 }
1590 #endif
1591
1592
1593 badvalue(vc) /* report bad variable value and exit */
1594 int vc;
1595 {
1596 fprintf(stderr, "%s: bad value for variable '%s'\n",
1597 progname, vnam(vc));
1598 exit(1);
1599 }
1600
1601
1602 syserr(s) /* report a system error and exit */
1603 char *s;
1604 {
1605 perror(s);
1606 exit(1);
1607 }