ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.38
Committed: Sat Jan 1 12:12:32 1994 UTC (30 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.37: +42 -32 lines
Log Message:
separated picture options so OPTFILE may be used by rtrace

File Contents

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