ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.40
Committed: Thu Apr 21 12:22:44 1994 UTC (30 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.39: +8 -0 lines
Log Message:
added a bit of paranoia to oconv() for incorrect system clocks

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.40 if (octreedate < scenedate) /* in case clock is off */
705     octreedate = scenedate;
706 greg 2.26 }
707     if (oct1name == vval(OCTREE)) /* no mkillum? */
708     oct1date = octreedate > matdate ? octreedate : matdate;
709     if (oct1date >= octreedate & oct1date >= matdate
710     & oct1date >= illumdate) /* all done */
711 greg 2.1 return;
712 greg 2.26 /* make octree0 */
713     if (oct0date < scenedate | oct0date < illumdate) {
714     /* build command */
715     if (octreedate)
716     sprintf(combuf, "oconv%s -i %s %s > %s", ocopts,
717     vval(OCTREE), vval(ILLUM), oct0name);
718     else if (vdef(MATERIAL))
719     sprintf(combuf, "oconv%s %s %s > %s", ocopts,
720     vval(MATERIAL), vval(ILLUM), oct0name);
721     else
722     sprintf(combuf, "oconv%s %s > %s", ocopts,
723     vval(ILLUM), oct0name);
724     if (runcom(combuf)) { /* run it */
725     fprintf(stderr,
726     "%s: error generating octree\n\t%s removed\n",
727     progname, oct0name);
728     unlink(oct0name);
729     exit(1);
730     }
731 greg 2.35 oct0date = time((time_t *)NULL);
732 greg 2.40 if (oct0date < octreedate) /* in case clock is off */
733     oct0date = octreedate;
734     if (oct0date < illumdate) /* ditto */
735     oct0date = illumdate;
736 greg 2.26 }
737     mkillumopts(mkopts); /* build mkillum command */
738     mktemp(illumtmp);
739     sprintf(combuf, "mkillum%s %s \"<\" %s > %s", mkopts,
740     oct0name, vval(ILLUM), illumtmp);
741     if (runcom(combuf)) { /* run it */
742     fprintf(stderr, "%s: error running mkillum\n", progname);
743     unlink(illumtmp);
744     exit(1);
745     }
746     /* make octree1 (frozen) */
747     if (octreedate)
748     sprintf(combuf, "oconv%s -f -i %s %s > %s", ocopts,
749     vval(OCTREE), illumtmp, oct1name);
750     else if (vdef(MATERIAL))
751     sprintf(combuf, "oconv%s -f %s %s > %s", ocopts,
752     vval(MATERIAL), illumtmp, oct1name);
753 greg 2.4 else
754 greg 2.26 sprintf(combuf, "oconv%s -f %s > %s", ocopts,
755     illumtmp, oct1name);
756 greg 2.4 if (runcom(combuf)) { /* run it */
757 greg 2.26 fprintf(stderr,
758     "%s: error generating octree\n\t%s removed\n",
759     progname, oct1name);
760     unlink(oct1name);
761 greg 2.1 exit(1);
762     }
763 greg 2.35 oct1date = time((time_t *)NULL);
764 greg 2.40 if (oct1date < oct0date) /* in case clock is off */
765     oct1date = oct0date;
766 greg 2.26 rmfile(illumtmp);
767 greg 2.1 }
768    
769    
770     char *
771     addarg(op, arg) /* add argument and advance pointer */
772     register char *op, *arg;
773     {
774     *op = ' ';
775     while (*++op = *arg++)
776     ;
777     return(op);
778     }
779    
780    
781     oconvopts(oo) /* get oconv options */
782 greg 2.2 register char *oo;
783 greg 2.1 {
784 greg 2.2 /* BEWARE: This may be called via setdefaults(), so no assumptions */
785    
786 greg 2.1 *oo = '\0';
787     if (vdef(OCONV))
788     addarg(oo, vval(OCONV));
789     }
790    
791    
792 greg 2.26 mkillumopts(mo) /* get mkillum options */
793     register char *mo;
794     {
795     /* BEWARE: This may be called via setdefaults(), so no assumptions */
796    
797     *mo = '\0';
798     if (vdef(MKILLUM))
799     addarg(mo, vval(MKILLUM));
800     }
801    
802    
803 greg 2.7 checkambfile() /* check date on ambient file */
804     {
805 greg 2.35 time_t afdate;
806 greg 2.7
807 greg 2.11 if (!vdef(AMBFILE))
808     return;
809 greg 2.26 if (!(afdate = fdate(vval(AMBFILE))))
810 greg 2.11 return;
811 greg 2.26 if (oct1date > afdate)
812 greg 2.11 rmfile(vval(AMBFILE));
813 greg 2.7 }
814    
815    
816 greg 2.2 double
817     ambval() /* compute ambient value */
818 greg 2.1 {
819 greg 2.3 if (vdef(EXPOSURE)) {
820 greg 2.2 if (vval(EXPOSURE)[0] == '+' || vval(EXPOSURE)[0] == '-')
821     return(.5/pow(2.,atof(vval(EXPOSURE))));
822 greg 2.20 return(.5/atof(vval(EXPOSURE)));
823 greg 2.3 }
824 greg 2.2 if (vlet(ZONE) == 'E')
825     return(10.);
826 greg 2.3 if (vlet(ZONE) == 'I')
827 greg 2.2 return(.01);
828 greg 2.3 badvalue(ZONE);
829 greg 2.30 }
830    
831    
832 greg 2.38 renderopts(op, po) /* set rendering options */
833     char *op, *po;
834 greg 2.30 {
835     switch(vscale(QUALITY)) {
836     case LOW:
837 greg 2.38 lowqopts(op, po);
838 greg 2.30 break;
839     case MEDIUM:
840 greg 2.38 medqopts(op, po);
841 greg 2.30 break;
842     case HIGH:
843 greg 2.38 hiqopts(op, po);
844 greg 2.30 break;
845     }
846 greg 2.2 }
847 greg 2.1
848 greg 2.2
849 greg 2.38 lowqopts(op, po) /* low quality rendering options */
850 greg 2.2 register char *op;
851 greg 2.38 char *po;
852 greg 2.2 {
853     double d, org[3], siz[3];
854    
855 greg 2.1 *op = '\0';
856 greg 2.38 *po = '\0';
857 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
858 greg 2.3 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
859     badvalue(ZONE);
860 greg 2.2 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
861 greg 2.39 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
862     badvalue(ZONE);
863 greg 2.2 getoctcube(org, &d);
864     d *= 3./(siz[0]+siz[1]+siz[2]);
865     switch (vscale(DETAIL)) {
866     case LOW:
867 greg 2.38 po = addarg(po, "-ps 16");
868     op = addarg(op, "-dp 64");
869 greg 2.2 sprintf(op, " -ar %d", (int)(4*d));
870     op += strlen(op);
871     break;
872     case MEDIUM:
873 greg 2.38 po = addarg(po, "-ps 8");
874     op = addarg(op, "-dp 128");
875 greg 2.2 sprintf(op, " -ar %d", (int)(8*d));
876     op += strlen(op);
877     break;
878     case HIGH:
879 greg 2.38 po = addarg(po, "-ps 4");
880     op = addarg(op, "-dp 256");
881 greg 2.2 sprintf(op, " -ar %d", (int)(16*d));
882     op += strlen(op);
883     break;
884     }
885 greg 2.38 po = addarg(po, "-pt .16");
886 greg 2.2 if (vbool(PENUMBRAS))
887     op = addarg(op, "-ds .4");
888 greg 2.4 else
889     op = addarg(op, "-ds 0");
890 greg 2.17 op = addarg(op, "-dt .2 -dc .25 -dr 0 -sj 0 -st .5");
891 greg 2.2 if (vdef(AMBFILE)) {
892     sprintf(op, " -af %s", vval(AMBFILE));
893     op += strlen(op);
894     } else
895     overture = 0;
896     switch (vscale(VARIABILITY)) {
897     case LOW:
898 greg 2.16 op = addarg(op, "-aa .4 -ad 64");
899 greg 2.2 break;
900     case MEDIUM:
901 greg 2.16 op = addarg(op, "-aa .3 -ad 128");
902 greg 2.2 break;
903     case HIGH:
904 greg 2.16 op = addarg(op, "-aa .25 -ad 256");
905 greg 2.2 break;
906     }
907     op = addarg(op, "-as 0");
908     d = ambval();
909     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
910     op += strlen(op);
911 greg 2.4 op = addarg(op, "-lr 3 -lw .02");
912 greg 2.1 if (vdef(RENDER))
913     op = addarg(op, vval(RENDER));
914     }
915    
916    
917 greg 2.38 medqopts(op, po) /* medium quality rendering options */
918 greg 2.2 register char *op;
919 greg 2.38 char *po;
920 greg 2.1 {
921 greg 2.2 double d, org[3], siz[3];
922 greg 2.1
923     *op = '\0';
924 greg 2.38 *po = '\0';
925 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
926 greg 2.3 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
927     badvalue(ZONE);
928 greg 2.2 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
929 greg 2.39 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
930     badvalue(ZONE);
931 greg 2.2 getoctcube(org, &d);
932     d *= 3./(siz[0]+siz[1]+siz[2]);
933     switch (vscale(DETAIL)) {
934     case LOW:
935 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8");
936 greg 2.23 op = addarg(op, "-dp 256");
937 greg 2.2 sprintf(op, " -ar %d", (int)(8*d));
938     op += strlen(op);
939     break;
940     case MEDIUM:
941 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6");
942 greg 2.23 op = addarg(op, "-dp 512");
943 greg 2.2 sprintf(op, " -ar %d", (int)(16*d));
944     op += strlen(op);
945     break;
946     case HIGH:
947 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4");
948 greg 2.23 op = addarg(op, "-dp 1024");
949 greg 2.2 sprintf(op, " -ar %d", (int)(32*d));
950     op += strlen(op);
951     break;
952     }
953 greg 2.38 po = addarg(po, "-pt .08");
954 greg 2.4 if (vbool(PENUMBRAS))
955 greg 2.28 op = addarg(op, "-ds .2 -dj .5");
956 greg 2.4 else
957 greg 2.2 op = addarg(op, "-ds .3");
958 greg 2.17 op = addarg(op, "-dt .1 -dc .5 -dr 1 -sj .7 -st .1");
959 greg 2.5 if (overture = vint(INDIRECT)) {
960     sprintf(op, " -ab %d", overture);
961     op += strlen(op);
962     }
963 greg 2.2 if (vdef(AMBFILE)) {
964     sprintf(op, " -af %s", vval(AMBFILE));
965     op += strlen(op);
966     } else
967     overture = 0;
968     switch (vscale(VARIABILITY)) {
969     case LOW:
970 greg 2.16 op = addarg(op, "-aa .25 -ad 196 -as 0");
971 greg 2.2 break;
972     case MEDIUM:
973 greg 2.16 op = addarg(op, "-aa .2 -ad 400 -as 64");
974 greg 2.2 break;
975     case HIGH:
976 greg 2.16 op = addarg(op, "-aa .15 -ad 768 -as 196");
977 greg 2.2 break;
978     }
979     d = ambval();
980     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
981     op += strlen(op);
982 greg 2.4 op = addarg(op, "-lr 6 -lw .002");
983 greg 2.1 if (vdef(RENDER))
984     op = addarg(op, vval(RENDER));
985     }
986    
987    
988 greg 2.38 hiqopts(op, po) /* high quality rendering options */
989 greg 2.2 register char *op;
990 greg 2.38 char *po;
991 greg 2.1 {
992 greg 2.2 double d, org[3], siz[3];
993 greg 2.1
994     *op = '\0';
995 greg 2.38 *po = '\0';
996 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
997 greg 2.3 &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6)
998     badvalue(ZONE);
999 greg 2.2 siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
1000 greg 2.39 if (siz[0] <= FTINY | siz[1] <= FTINY | siz[2] <= FTINY)
1001     badvalue(ZONE);
1002 greg 2.2 getoctcube(org, &d);
1003     d *= 3./(siz[0]+siz[1]+siz[2]);
1004     switch (vscale(DETAIL)) {
1005     case LOW:
1006 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8");
1007 greg 2.23 op = addarg(op, "-dp 1024");
1008 greg 2.2 sprintf(op, " -ar %d", (int)(16*d));
1009     op += strlen(op);
1010     break;
1011     case MEDIUM:
1012 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5");
1013 greg 2.23 op = addarg(op, "-dp 2048");
1014 greg 2.2 sprintf(op, " -ar %d", (int)(32*d));
1015     op += strlen(op);
1016     break;
1017     case HIGH:
1018 greg 2.38 po = addarg(po, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3");
1019 greg 2.23 op = addarg(op, "-dp 4096");
1020 greg 2.2 sprintf(op, " -ar %d", (int)(64*d));
1021     op += strlen(op);
1022     break;
1023     }
1024 greg 2.38 po = addarg(po, "-pt .04");
1025 greg 2.4 if (vbool(PENUMBRAS))
1026     op = addarg(op, "-ds .1 -dj .7");
1027     else
1028 greg 2.2 op = addarg(op, "-ds .2");
1029 greg 2.17 op = addarg(op, "-dt .05 -dc .75 -dr 3 -sj 1 -st .01");
1030 greg 2.2 sprintf(op, " -ab %d", overture=vint(INDIRECT)+1);
1031     op += strlen(op);
1032     if (vdef(AMBFILE)) {
1033     sprintf(op, " -af %s", vval(AMBFILE));
1034     op += strlen(op);
1035     } else
1036     overture = 0;
1037     switch (vscale(VARIABILITY)) {
1038     case LOW:
1039 greg 2.16 op = addarg(op, "-aa .15 -ad 256 -as 0");
1040 greg 2.2 break;
1041     case MEDIUM:
1042 greg 2.16 op = addarg(op, "-aa .125 -ad 512 -as 256");
1043 greg 2.2 break;
1044     case HIGH:
1045 greg 2.16 op = addarg(op, "-aa .08 -ad 1024 -as 512");
1046 greg 2.2 break;
1047     }
1048     d = ambval();
1049     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
1050     op += strlen(op);
1051 greg 2.4 op = addarg(op, "-lr 12 -lw .0005");
1052 greg 2.1 if (vdef(RENDER))
1053     op = addarg(op, vval(RENDER));
1054     }
1055    
1056    
1057     xferopts(ro) /* transfer options if indicated */
1058     char *ro;
1059     {
1060     int fd, n;
1061 greg 2.10 register char *cp;
1062 greg 2.1
1063     n = strlen(ro);
1064     if (n < 2)
1065     return;
1066     if (vdef(OPTFILE)) {
1067 greg 2.10 for (cp = ro; cp[1]; cp++)
1068     if (isspace(cp[1]) && cp[2] == '-' && isalpha(cp[3]))
1069     *cp = '\n';
1070     else
1071     *cp = cp[1];
1072     *cp = '\n';
1073     fd = open(vval(OPTFILE), O_WRONLY|O_CREAT|O_TRUNC, 0666);
1074     if (fd < 0 || write(fd, ro, n) != n || close(fd) < 0)
1075 greg 2.3 syserr(vval(OPTFILE));
1076 greg 2.15 sprintf(ro, " @%s", vval(OPTFILE));
1077 greg 2.1 }
1078     #ifdef MSDOS
1079     else if (n > 50) {
1080 greg 2.8 setenv("ROPT", ro+1);
1081 greg 2.1 strcpy(ro, " $ROPT");
1082     }
1083     #endif
1084     }
1085    
1086    
1087     pfiltopts(po) /* get pfilt options */
1088     register char *po;
1089     {
1090     *po = '\0';
1091     if (vdef(EXPOSURE)) {
1092     po = addarg(po, "-1 -e");
1093     po = addarg(po, vval(EXPOSURE));
1094     }
1095 greg 2.12 switch (vscale(QUALITY)) {
1096     case MEDIUM:
1097     po = addarg(po, "-r 1");
1098     break;
1099     case HIGH:
1100 greg 2.14 po = addarg(po, "-m .25");
1101 greg 2.12 break;
1102     }
1103 greg 2.1 if (vdef(PFILT))
1104     po = addarg(po, vval(PFILT));
1105     }
1106    
1107    
1108     matchword(s1, s2) /* match white-delimited words */
1109     register char *s1, *s2;
1110     {
1111     while (isspace(*s1)) s1++;
1112     while (isspace(*s2)) s2++;
1113     while (*s1 && !isspace(*s1))
1114     if (*s1++ != *s2++)
1115     return(0);
1116     return(!*s2 || isspace(*s2));
1117     }
1118    
1119    
1120     char *
1121     specview(vs) /* get proper view spec from vs */
1122     register char *vs;
1123     {
1124 greg 2.3 static char vup[7][12] = {"-vu 0 0 -1","-vu 0 -1 0","-vu -1 0 0",
1125     "-vu 0 0 1", "-vu 1 0 0","-vu 0 1 0","-vu 0 0 1"};
1126 greg 2.1 static char viewopts[128];
1127     register char *cp;
1128 greg 2.3 int xpos, ypos, zpos, viewtype, upax;
1129     register int i;
1130 greg 2.1 double cent[3], dim[3], mult, d;
1131    
1132 greg 2.9 if (vs == NULL || *vs == '-')
1133 greg 2.1 return(vs);
1134 greg 2.3 upax = 0; /* get the up vector */
1135     if (vdef(UP)) {
1136     if (vval(UP)[0] == '-' || vval(UP)[0] == '+')
1137     upax = 1-'X'+UPPER(vval(UP)[1]);
1138     else
1139     upax = 1-'X'+vlet(UP);
1140     if (upax < 1 | upax > 3)
1141     badvalue(UP);
1142     if (vval(UP)[0] == '-')
1143     upax = -upax;
1144     }
1145 greg 2.1 /* check standard view names */
1146     xpos = ypos = zpos = 0;
1147     if (*vs == 'X') {
1148     xpos = 1; vs++;
1149     } else if (*vs == 'x') {
1150     xpos = -1; vs++;
1151     }
1152     if (*vs == 'Y') {
1153     ypos = 1; vs++;
1154     } else if (*vs == 'y') {
1155     ypos = -1; vs++;
1156     }
1157     if (*vs == 'Z') {
1158     zpos = 1; vs++;
1159     } else if (*vs == 'z') {
1160     zpos = -1; vs++;
1161     }
1162 greg 2.3 viewtype = 'v';
1163 greg 2.1 if (*vs == 'v' | *vs == 'l' | *vs == 'a' | *vs == 'h')
1164     viewtype = *vs++;
1165     cp = viewopts;
1166 greg 2.3 if ((!*vs || isspace(*vs)) && (xpos|ypos|zpos)) { /* got one! */
1167 greg 2.1 *cp++ = '-'; *cp++ = 'v'; *cp++ = 't'; *cp++ = viewtype;
1168     if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf",
1169     &cent[0], &dim[0], &cent[1], &dim[1],
1170 greg 2.3 &cent[2], &dim[2]) != 6)
1171     badvalue(ZONE);
1172     for (i = 0; i < 3; i++) {
1173     dim[i] -= cent[i];
1174 greg 2.39 if (dim[i] <= FTINY)
1175     badvalue(ZONE);
1176 greg 2.3 cent[i] += .5*dim[i];
1177 greg 2.1 }
1178 greg 2.3 mult = vlet(ZONE)=='E' ? 2. : .45 ;
1179 greg 2.1 sprintf(cp, " -vp %.2g %.2g %.2g -vd %.2g %.2g %.2g",
1180     cent[0]+xpos*mult*dim[0],
1181     cent[1]+ypos*mult*dim[1],
1182     cent[2]+zpos*mult*dim[2],
1183     -xpos*dim[0], -ypos*dim[1], -zpos*dim[2]);
1184     cp += strlen(cp);
1185 greg 2.3 /* redirect up axis if necessary */
1186     switch (upax) {
1187     case 3: /* plus or minus Z axis */
1188     case -3:
1189     case 0:
1190     if (!(xpos|ypos))
1191     upax = 2;
1192 greg 2.1 break;
1193 greg 2.3 case 2: /* plus or minus Y axis */
1194     case -2:
1195     if (!(xpos|zpos))
1196     upax = 1;
1197     break;
1198     case 1: /* plus or minus X axis */
1199     case -1:
1200     if (!(ypos|zpos))
1201     upax = 3;
1202     break;
1203 greg 2.1 }
1204 greg 2.3 cp = addarg(cp, vup[upax+3]);
1205 greg 2.1 switch (viewtype) {
1206     case 'v':
1207     cp = addarg(cp, "-vh 45 -vv 45");
1208     break;
1209     case 'l':
1210     d = sqrt(dim[0]*dim[0]+dim[1]*dim[1]+dim[2]*dim[2]);
1211     sprintf(cp, " -vh %.2g -vv %.2g", d, d);
1212     cp += strlen(cp);
1213     break;
1214     case 'a':
1215     case 'h':
1216     cp = addarg(cp, "-vh 180 -vv 180");
1217     break;
1218     }
1219 greg 2.3 } else {
1220 greg 2.4 while (!isspace(*vs)) /* else skip id */
1221     if (!*vs++)
1222     return(NULL);
1223 greg 2.3 if (upax) { /* specify up vector */
1224     strcpy(cp, vup[upax+3]);
1225     cp += strlen(cp);
1226     }
1227     }
1228 greg 2.26 if (cp == viewopts) /* append any additional options */
1229     vs++; /* skip prefixed space if unneeded */
1230     strcpy(cp, vs);
1231 greg 2.8 #ifdef MSDOS
1232     if (strlen(viewopts) > 40) {
1233     setenv("VIEW", viewopts);
1234     return("$VIEW");
1235     }
1236     #endif
1237 greg 2.1 return(viewopts);
1238     }
1239    
1240    
1241     char *
1242     getview(n, vn) /* get view n, or NULL if none */
1243     int n;
1244 greg 2.8 char *vn; /* returned view name */
1245 greg 2.1 {
1246 greg 2.19 register char *mv;
1247 greg 2.1
1248 greg 2.8 if (viewselect != NULL) { /* command-line selected */
1249 greg 2.1 if (n) /* only do one */
1250     return(NULL);
1251     if (viewselect[0] == '-') { /* already specified */
1252     if (vn != NULL) *vn = '\0';
1253     return(viewselect);
1254     }
1255     if (vn != NULL) {
1256     for (mv = viewselect; *mv && !isspace(*mv);
1257     *vn++ = *mv++)
1258     ;
1259     *vn = '\0';
1260     }
1261 greg 2.19 /* view number? */
1262 greg 2.20 if (isint(viewselect))
1263 greg 2.19 return(specview(nvalue(vv+VIEW, atoi(viewselect)-1)));
1264 greg 2.1 /* check list */
1265     while ((mv = nvalue(vv+VIEW, n++)) != NULL)
1266     if (matchword(viewselect, mv))
1267     return(specview(mv));
1268     return(specview(viewselect)); /* standard view? */
1269     }
1270 greg 2.8 mv = nvalue(vv+VIEW, n); /* use view n */
1271     if (vn != NULL & mv != NULL) {
1272 greg 2.19 register char *mv2 = mv;
1273     if (*mv2 != '-')
1274     while (*mv2 && !isspace(*mv2))
1275     *vn++ = *mv2++;
1276 greg 2.1 *vn = '\0';
1277     }
1278 greg 2.8 return(specview(mv));
1279 greg 2.20 }
1280    
1281    
1282 greg 2.21 printview(vopts) /* print out selected view */
1283     register char *vopts;
1284 greg 2.20 {
1285 greg 2.24 extern char *atos(), *getenv();
1286 greg 2.20 char buf[256];
1287     FILE *fp;
1288 greg 2.21 register char *cp;
1289 greg 2.20
1290     if (vopts == NULL)
1291     return(-1);
1292     fputs("VIEW=", stdout);
1293     do {
1294     if (matchword(vopts, "-vf")) { /* expand view file */
1295     vopts = sskip(vopts);
1296     if (!*atos(buf, sizeof(buf), vopts))
1297     return(-1);
1298     if ((fp = fopen(buf, "r")) == NULL)
1299     return(-1);
1300     for (buf[sizeof(buf)-2] = '\n';
1301     fgets(buf, sizeof(buf), fp) != NULL &&
1302     buf[0] != '\n';
1303     buf[sizeof(buf)-2] = '\n') {
1304     if (buf[sizeof(buf)-2] != '\n') {
1305     ungetc(buf[sizeof(buf)-2], fp);
1306     buf[sizeof(buf)-2] = '\0';
1307     }
1308     if (matchword(buf, "VIEW=") ||
1309     matchword(buf, "rview")) {
1310     for (cp = sskip(buf); *cp && *cp != '\n'; cp++)
1311     putchar(*cp);
1312     }
1313     }
1314     fclose(fp);
1315     vopts = sskip(vopts);
1316     } else {
1317     while (isspace(*vopts))
1318     vopts++;
1319     putchar(' ');
1320 greg 2.24 #ifdef MSDOS
1321     if (*vopts == '$') { /* expand env. var. */
1322     if (!*atos(buf, sizeof(buf), vopts+1))
1323     return(-1);
1324     if ((cp = getenv(buf)) == NULL)
1325     return(-1);
1326     fputs(cp, stdout);
1327     vopts = sskip(vopts);
1328     } else
1329     #endif
1330     while (*vopts && !isspace(*vopts))
1331     putchar(*vopts++);
1332 greg 2.20 }
1333     } while (*vopts++);
1334     putchar('\n');
1335     return(0);
1336 greg 2.1 }
1337    
1338    
1339 greg 2.38 rview(opts, po) /* run rview with first view */
1340     char *opts, *po;
1341 greg 2.1 {
1342 greg 2.21 char *vw;
1343 greg 2.1 char combuf[512];
1344     /* build command */
1345 greg 2.21 if ((vw = getview(0, NULL)) == NULL)
1346     return;
1347     if (sayview)
1348     printview(vw);
1349 greg 2.38 sprintf(combuf, "rview %s%s%s -R %s ", vw, po, opts, rifname);
1350 greg 2.1 if (rvdevice != NULL)
1351     sprintf(combuf+strlen(combuf), "-o %s ", rvdevice);
1352 greg 2.29 if (vdef(EXPOSURE))
1353     sprintf(combuf+strlen(combuf), "-pe %s ", vval(EXPOSURE));
1354 greg 2.26 strcat(combuf, oct1name);
1355 greg 2.4 if (runcom(combuf)) { /* run it */
1356 greg 2.1 fprintf(stderr, "%s: error running rview\n", progname);
1357     exit(1);
1358     }
1359     }
1360    
1361    
1362 greg 2.38 rpict(opts, po) /* run rpict and pfilt for each view */
1363     char *opts, *po;
1364 greg 2.1 {
1365 greg 2.2 char combuf[1024];
1366 greg 2.3 char rawfile[MAXPATH], picfile[MAXPATH], rep[MAXPATH+16], res[32];
1367     char pfopts[128];
1368 greg 2.1 char vs[32], *vw;
1369     int vn, mult;
1370     /* get pfilt options */
1371     pfiltopts(pfopts);
1372     /* get resolution, reporting */
1373 greg 2.31 switch (vscale(QUALITY)) {
1374     case LOW:
1375     mult = 1;
1376     break;
1377     case MEDIUM:
1378     mult = 2;
1379     break;
1380     case HIGH:
1381     mult = 3;
1382     break;
1383     }
1384 greg 2.1 {
1385     int xres, yres;
1386     double aspect;
1387     int n;
1388     n = sscanf(vval(RESOLUTION), "%d %d %lf", &xres, &yres, &aspect);
1389     if (n == 3)
1390     sprintf(res, "-x %d -y %d -pa %.3f",
1391     mult*xres, mult*yres, aspect);
1392     else if (n) {
1393     if (n == 1) yres = xres;
1394     sprintf(res, "-x %d -y %d", mult*xres, mult*yres);
1395 greg 2.3 } else
1396     badvalue(RESOLUTION);
1397 greg 2.1 }
1398     rep[0] = '\0';
1399     if (vdef(REPORT)) {
1400     double minutes;
1401     int n;
1402     n = sscanf(vval(REPORT), "%lf %s", &minutes, rawfile);
1403     if (n == 2)
1404     sprintf(rep, " -t %d -e %s", (int)(minutes*60), rawfile);
1405     else if (n == 1)
1406     sprintf(rep, " -t %d", (int)(minutes*60));
1407 greg 2.3 else
1408     badvalue(REPORT);
1409 greg 2.1 }
1410     /* do each view */
1411     vn = 0;
1412     while ((vw = getview(vn++, vs)) != NULL) {
1413 greg 2.21 if (sayview)
1414     printview(vw);
1415 greg 2.1 if (!vs[0])
1416     sprintf(vs, "%d", vn);
1417     sprintf(picfile, "%s_%s.pic", vval(PICTURE), vs);
1418     /* check date on picture */
1419 greg 2.26 if (fdate(picfile) >= oct1date)
1420 greg 2.1 continue;
1421     /* build rpict command */
1422     sprintf(rawfile, "%s_%s.raw", vval(PICTURE), vs);
1423 greg 2.26 if (fdate(rawfile) >= oct1date) /* recover */
1424 greg 2.38 sprintf(combuf, "rpict%s%s%s -ro %s %s",
1425     rep, po, opts, rawfile, oct1name);
1426 greg 2.1 else {
1427     if (overture) { /* run overture calculation */
1428     sprintf(combuf,
1429     "rpict%s %s%s -x 64 -y 64 -ps 1 %s > %s",
1430     rep, vw, opts,
1431 greg 2.26 oct1name, overfile);
1432 greg 2.4 if (runcom(combuf)) {
1433 greg 2.1 fprintf(stderr,
1434 greg 2.6 "%s: error in overture for view %s\n",
1435     progname, vs);
1436 greg 2.1 exit(1);
1437     }
1438 greg 2.6 #ifdef NIX
1439     rmfile(overfile);
1440     #endif
1441 greg 2.1 }
1442 greg 2.38 sprintf(combuf, "rpict%s %s %s%s%s %s > %s",
1443     rep, vw, res, po, opts,
1444 greg 2.29 oct1name, rawfile);
1445 greg 2.1 }
1446 greg 2.4 if (runcom(combuf)) { /* run rpict */
1447 greg 2.1 fprintf(stderr, "%s: error rendering view %s\n",
1448     progname, vs);
1449     exit(1);
1450     }
1451     /* build pfilt command */
1452     if (mult > 1)
1453     sprintf(combuf, "pfilt%s -x /%d -y /%d %s > %s",
1454     pfopts, mult, mult, rawfile, picfile);
1455     else
1456     sprintf(combuf, "pfilt%s %s > %s", pfopts,
1457     rawfile, picfile);
1458 greg 2.4 if (runcom(combuf)) { /* run pfilt */
1459 greg 2.1 fprintf(stderr,
1460     "%s: error filtering view %s\n\t%s removed\n",
1461     progname, vs, picfile);
1462     unlink(picfile);
1463     exit(1);
1464     }
1465     /* remove raw file */
1466 greg 2.4 rmfile(rawfile);
1467     }
1468     }
1469    
1470    
1471     runcom(cs) /* run command */
1472     char *cs;
1473     {
1474     if (!silent) /* echo it */
1475     printf("\t%s\n", cs);
1476     if (noaction)
1477     return(0);
1478     fflush(stdout); /* flush output and pass to shell */
1479     return(system(cs));
1480     }
1481    
1482    
1483     rmfile(fn) /* remove a file */
1484     char *fn;
1485     {
1486     if (!silent)
1487 greg 2.1 #ifdef MSDOS
1488 greg 2.4 printf("\tdel %s\n", fn);
1489 greg 2.1 #else
1490 greg 2.4 printf("\trm -f %s\n", fn);
1491 greg 2.1 #endif
1492 greg 2.4 if (noaction)
1493     return(0);
1494     return(unlink(fn));
1495 greg 2.3 }
1496 greg 2.8
1497    
1498     #ifdef MSDOS
1499     setenv(vname, value) /* set an environment variable */
1500     char *vname, *value;
1501     {
1502     register char *evp;
1503    
1504     evp = bmalloc(strlen(vname)+strlen(value)+2);
1505     if (evp == NULL)
1506     syserr(progname);
1507     sprintf(evp, "%s=%s", vname, value);
1508     if (putenv(evp) != 0) {
1509     fprintf(stderr, "%s: out of environment space\n", progname);
1510     exit(1);
1511     }
1512     if (!silent)
1513     printf("set %s\n", evp);
1514     }
1515     #endif
1516 greg 2.3
1517    
1518     badvalue(vc) /* report bad variable value and exit */
1519     int vc;
1520     {
1521     fprintf(stderr, "%s: bad value for variable '%s'\n",
1522     progname, vnam(vc));
1523     exit(1);
1524     }
1525    
1526    
1527     syserr(s) /* report a system error and exit */
1528     char *s;
1529     {
1530     perror(s);
1531     exit(1);
1532 greg 2.1 }