ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.43
Committed: Thu Jul 6 12:15:40 1995 UTC (28 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.42: +28 -3 lines
Log Message:
added RAWSAVE variable to rad to save original rpict output

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