ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.2
Committed: Thu Mar 11 11:39:48 1993 UTC (31 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +290 -59 lines
Log Message:
added routines to set rendering options

File Contents

# User Rev Content
1 greg 2.1 /* Copyright (c) 1993 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Executive program for oconv, rpict and pfilt
9     */
10    
11     #include "standard.h"
12     #include "paths.h"
13     #include <ctype.h>
14    
15    
16     typedef struct {
17     char *name; /* variable name */
18     short nick; /* # characters required for nickname */
19     short nass; /* # assignments made */
20     char *value; /* assigned value(s) */
21     int (*fixval)(); /* assignment checking function */
22     } VARIABLE;
23    
24     int onevalue(), catvalues();
25    
26     /* variables */
27     #define OBJECT 0 /* object files */
28     #define SCENE 1 /* scene files */
29     #define MATERIAL 2 /* material files */
30     #define RENDER 3 /* rendering options */
31     #define OCONV 4 /* oconv options */
32     #define PFILT 5 /* pfilt options */
33     #define VIEW 6 /* view(s) for picture(s) */
34     #define ZONE 7 /* simulation zone */
35     #define QUALITY 8 /* desired rendering quality */
36     #define OCTREE 9 /* octree file name */
37     #define PICTURE 10 /* picture file name */
38     #define AMBFILE 11 /* ambient file name */
39     #define OPTFILE 12 /* rendering options file */
40     #define EXPOSURE 13 /* picture exposure setting */
41     #define RESOLUTION 14 /* maximum picture resolution */
42     #define UP 15 /* view up (X, Y or Z) */
43     #define INDIRECT 16 /* indirection in lighting */
44     #define DETAIL 17 /* level of scene detail */
45     #define PENUMBRAS 18 /* shadow penumbras are desired */
46     #define VARIABILITY 19 /* level of light variability */
47     #define REPORT 20 /* report frequency and errfile */
48     /* total number of variables */
49     #define NVARS 21
50    
51     VARIABLE vv[NVARS] = { /* variable-value pairs */
52     {"objects", 3, 0, NULL, catvalues},
53     {"scene", 3, 0, NULL, catvalues},
54     {"materials", 3, 0, NULL, catvalues},
55     {"render", 3, 0, NULL, catvalues},
56     {"oconv", 3, 0, NULL, catvalues},
57     {"pfilt", 2, 0, NULL, catvalues},
58     {"view", 2, 0, NULL, NULL},
59     {"ZONE", 2, 0, NULL, onevalue},
60     {"QUALITY", 3, 0, NULL, onevalue},
61     {"OCTREE", 3, 0, NULL, onevalue},
62     {"PICTURE", 3, 0, NULL, onevalue},
63     {"AMBFILE", 3, 0, NULL, onevalue},
64     {"OPTFILE", 3, 0, NULL, onevalue},
65     {"EXPOSURE", 3, 0, NULL, onevalue},
66     {"RESOLUTION", 3, 0, NULL, onevalue},
67     {"UP", 2, 0, NULL, onevalue},
68     {"INDIRECT", 3, 0, NULL, onevalue},
69     {"DETAIL", 3, 0, NULL, onevalue},
70     {"PENUMBRAS", 3, 0, NULL, onevalue},
71     {"VARIABILITY", 3, 0, NULL, onevalue},
72     {"REPORT", 3, 0, NULL, onevalue},
73     };
74    
75     VARIABLE *matchvar();
76     char *nvalue();
77     int vscale();
78    
79     #define vnam(vc) (vv[vc].name)
80     #define vdef(vc) (vv[vc].nass)
81     #define vval(vc) (vv[vc].value)
82     #define vint(vc) atoi(vval(vc))
83     #define vlet(vc) (vval(vc)[0]&~0x20)
84     #define vbool(vc) (vlet(vc)=='T')
85    
86     #define HIGH 2
87     #define MEDIUM 1
88     #define LOW 0
89    
90     int lowqopts(), medqopts(), hiqopts();
91     int (*setqopts[3])() = {lowqopts, medqopts, hiqopts};
92    
93     #define renderopts (*setqopts[vscale(QUALITY)])
94    
95 greg 2.2 extern long fdate(), time();
96 greg 2.1
97     long scenedate; /* date of latest scene or object file */
98     long octreedate; /* date of octree */
99    
100     int explicate = 0; /* explicate variables */
101     int silent = 0; /* do work silently */
102     int noaction = 0; /* don't do anything */
103     char *rvdevice = NULL; /* rview output device */
104     char *viewselect = NULL; /* specific view only */
105    
106     int overture = 0; /* overture calculation needed */
107    
108     char *progname; /* global argv[0] */
109    
110     char radname[MAXPATH]; /* root Radiance file name */
111    
112    
113     main(argc, argv)
114     int argc;
115     char *argv[];
116     {
117     char ropts[512];
118     int i;
119    
120     progname = argv[0];
121     /* get options */
122     for (i = 1; i < argc && argv[i][0] == '-'; i++)
123     switch (argv[i][1]) {
124     case 's':
125     silent++;
126     break;
127     case 'n':
128     noaction++;
129     break;
130     case 'e':
131     explicate++;
132     break;
133     case 'o':
134     rvdevice = argv[++i];
135     break;
136     case 'v':
137     viewselect = argv[++i];
138     break;
139     default:
140     goto userr;
141     }
142     if (i >= argc)
143     goto userr;
144     /* assign Radiance root file name */
145     rootname(radname, argv[i]);
146     /* load variable values */
147     load(argv[i]);
148     /* get any additional assignments */
149     for (i++; i < argc; i++)
150     setvariable(argv[i]);
151     /* check assignments */
152     checkvalues();
153     /* check files and dates */
154     checkfiles();
155     /* set default values as necessary */
156     setdefaults();
157     /* print all values if requested */
158     if (explicate)
159     printvals();
160     /* run simulation */
161     oconv();
162     renderopts(ropts);
163     xferopts(ropts);
164     if (rvdevice != NULL)
165     rview(ropts);
166     else
167     rpict(ropts);
168     exit(0);
169     userr:
170     fprintf(stderr,
171     "Usage: %s [-s][-n][-v view][-o dev] rfile [VAR=value ..]\n",
172     progname);
173     exit(1);
174     }
175    
176    
177     rootname(rn, fn) /* remove tail from end of fn */
178     register char *rn, *fn;
179     {
180     char *tp, *dp;
181    
182     for (tp = NULL, dp = rn; *rn = *fn++; rn++)
183     if (ISDIRSEP(*rn))
184     dp = rn;
185     else if (*rn == '.')
186     tp = rn;
187     if (tp != NULL && tp > dp)
188     *tp = '\0';
189     }
190    
191    
192     load(rfname) /* load Radiance simulation file */
193     char *rfname;
194     {
195     FILE *fp;
196     char buf[256];
197     register char *cp;
198    
199     if (rfname == NULL)
200     fp = stdin;
201     else if ((fp = fopen(rfname, "r")) == NULL) {
202     perror(rfname);
203     exit(1);
204     }
205     while (fgetline(buf, sizeof(buf), fp) != NULL) {
206     for (cp = buf; *cp; cp++) {
207     switch (*cp) {
208     case '\\':
209     case '\n':
210     *cp = ' ';
211     continue;
212     case '#':
213     *cp = '\0';
214     break;
215     }
216     break;
217     }
218     setvariable(buf);
219     }
220     fclose(fp);
221     }
222    
223    
224     setvariable(ass) /* assign variable according to string */
225     register char *ass;
226     {
227     char varname[32];
228     register char *cp;
229     register VARIABLE *vp;
230     register int i;
231     int n;
232    
233     while (isspace(*ass)) /* skip leading space */
234     ass++;
235     cp = varname; /* extract name */
236     while (cp < varname+sizeof(varname)-1
237     && *ass && !isspace(*ass) && *ass != '=')
238     *cp++ = *ass++;
239     *cp = '\0';
240     if (!varname[0])
241     return; /* no variable name! */
242     /* trim value */
243     while (isspace(*ass) || *ass == '=')
244     ass++;
245     cp = ass + strlen(ass);
246     do
247     *cp-- = '\0';
248     while (cp >= ass && isspace(*cp));
249     n = cp - ass + 1;
250     if (!n) {
251     fprintf(stderr, "%s: warning - missing value for variable '%s'\n",
252     progname, varname);
253     return;
254     }
255     /* match variable from list */
256     vp = matchvar(varname);
257     if (vp == NULL) {
258     fprintf(stderr, "%s: unknown variable '%s'\n",
259     progname, varname);
260     exit(1);
261     }
262     /* assign new value */
263     cp = vp->value; i = vp->nass;
264     while (i--)
265     while (*cp++)
266     ;
267     i = cp - vp->value;
268     vp->value = realloc(vp->value, i+n+1);
269     if (vp->value == NULL) {
270     perror(progname);
271     exit(1);
272     }
273     strcpy(vp->value+i, ass);
274     vp->nass++;
275     }
276    
277    
278     VARIABLE *
279     matchvar(nam) /* match a variable by its name */
280     char *nam;
281     {
282     int n = strlen(nam);
283     register int i;
284    
285     for (i = 0; i < NVARS; i++)
286     if (n >= vv[i].nick && !strncmp(nam, vv[i].name, n))
287     return(vv+i);
288     return(NULL);
289     }
290    
291    
292     char *
293     nvalue(vp, n) /* return nth variable value */
294     VARIABLE *vp;
295     register int n;
296     {
297     register char *cp;
298    
299     if (vp == NULL || n < 0 || n >= vp->nass)
300     return(NULL);
301     cp = vp->value;
302     while (n--)
303     while (*cp++)
304     ;
305     return(cp);
306     }
307    
308    
309     int
310     vscale(vc) /* return scale for variable vc */
311     int vc;
312     {
313     switch(vlet(vc)) {
314     case 'H':
315     return(HIGH);
316     case 'M':
317     return(MEDIUM);
318     case 'L':
319     return(LOW);
320     }
321     fprintf(stderr, "%s: illegal value for variable '%s' (%s)\n",
322     progname, vnam(vc), vval(vc));
323     exit(1);
324     }
325    
326    
327     checkvalues() /* check assignments */
328     {
329     register int i;
330    
331     for (i = 0; i < NVARS; i++)
332     if (vv[i].fixval != NULL)
333     (*vv[i].fixval)(vv+i);
334     }
335    
336    
337     onevalue(vp) /* only one assignment for this variable */
338     register VARIABLE *vp;
339     {
340     if (vp->nass < 2)
341     return;
342     fprintf(stderr, "%s: warning - multiple assignment of variable '%s'\n",
343     progname, vp->name);
344 greg 2.2 do
345 greg 2.1 vp->value += strlen(vp->value)+1;
346 greg 2.2 while (--vp->nass > 1);
347 greg 2.1 }
348    
349    
350     catvalues(vp) /* concatenate variable values */
351     register VARIABLE *vp;
352     {
353     register char *cp;
354    
355     if (vp->nass < 2)
356     return;
357     for (cp = vp->value; vp->nass > 1; vp->nass--) {
358     while (*cp)
359     cp++;
360     *cp++ = ' ';
361     }
362     }
363    
364    
365     long
366     checklast(fnames) /* check files and find most recent */
367     register char *fnames;
368     {
369     char thisfile[MAXPATH];
370     long thisdate, lastdate = -1;
371     register char *cp;
372    
373     while (*fnames) {
374     while (isspace(*fnames)) fnames++;
375     cp = thisfile;
376     while (*fnames && !isspace(*fnames)) *cp++ = *fnames++;
377     *cp = '\0';
378     if ((thisdate = fdate(thisfile)) < 0) {
379     perror(thisfile);
380     exit(1);
381     }
382     if (thisdate > lastdate)
383     lastdate = thisdate;
384     }
385     return(lastdate);
386     }
387    
388    
389     checkfiles() /* check for existence and modified times */
390     {
391 greg 2.2 char *cp;
392 greg 2.1 long objdate;
393    
394 greg 2.2 if (!vdef(OCTREE)) {
395     if ((cp = bmalloc(strlen(radname)+5)) == NULL) {
396     perror(progname);
397     exit(1);
398     }
399     sprintf(cp, "%s.oct", radname);
400     vval(OCTREE) = cp;
401     vdef(OCTREE)++;
402     }
403     octreedate = fdate(vval(OCTREE));
404 greg 2.1 scenedate = -1;
405     if (vdef(SCENE)) {
406     scenedate = checklast(vval(SCENE));
407     if (vdef(OBJECT)) {
408     objdate = checklast(vval(OBJECT));
409     if (objdate > scenedate)
410     scenedate = objdate;
411     }
412     }
413     if (octreedate < 0 & scenedate < 0) {
414 greg 2.2 fprintf(stderr, "%s: need '%s' or '%s'\n", progname,
415     vnam(OCTREE), vnam(SCENE));
416 greg 2.1 exit(1);
417     }
418     }
419    
420    
421 greg 2.2 getoctcube(org, sizp) /* get octree bounding cube */
422     double org[3], *sizp;
423 greg 2.1 {
424 greg 2.2 extern FILE *popen();
425     static double oorg[3], osiz = 0.;
426     char buf[MAXPATH+16];
427 greg 2.1 FILE *fp;
428    
429 greg 2.2 if (osiz <= FTINY) {
430     oconv(); /* does nothing if done already */
431     sprintf(buf, "getinfo -d < %s", vval(OCTREE));
432     if ((fp = popen(buf, "r")) == NULL) {
433     perror("getinfo");
434     exit(1);
435     }
436     if (fscanf(fp, "%lf %lf %lf %lf", &oorg[0], &oorg[1],
437     &oorg[2], &osiz) != 4) {
438     fprintf(stderr,
439     "%s: error reading bounding cube from getinfo\n",
440     progname);
441     exit(1);
442     }
443     pclose(fp);
444 greg 2.1 }
445 greg 2.2 org[0] = oorg[0]; org[1] = oorg[1]; org[2] = oorg[2]; *sizp = osiz;
446     }
447    
448    
449     setdefaults() /* set default values for unassigned var's */
450     {
451     double org[3], size;
452     char buf[128];
453    
454 greg 2.1 if (!vdef(ZONE)) {
455 greg 2.2 getoctcube(org, &size);
456     sprintf(buf, "E %g %g %g %g %g %g", org[0], org[0]+size,
457     org[1], org[1]+size, org[2], org[2]+size);
458 greg 2.1 vval(ZONE) = savqstr(buf);
459     vdef(ZONE)++;
460     }
461     if (!vdef(UP)) {
462     vval(UP) = "Z";
463     vdef(UP)++;
464     }
465     if (!vdef(INDIRECT)) {
466     vval(INDIRECT) = "0";
467     vdef(INDIRECT)++;
468     }
469     if (!vdef(QUALITY)) {
470     vval(QUALITY) = "L";
471     vdef(QUALITY)++;
472     }
473     if (!vdef(RESOLUTION)) {
474     vval(RESOLUTION) = "512";
475     vdef(RESOLUTION)++;
476     }
477     if (!vdef(PICTURE)) {
478     vval(PICTURE) = radname;
479     vdef(PICTURE)++;
480     }
481     if (!vdef(VIEW)) {
482     vval(VIEW) = "X";
483     vdef(VIEW)++;
484     }
485     if (!vdef(DETAIL)) {
486     vval(DETAIL) = "M";
487     vdef(DETAIL)++;
488     }
489     if (!vdef(PENUMBRAS)) {
490     vval(PENUMBRAS) = "F";
491     vdef(PENUMBRAS)++;
492     }
493     if (!vdef(VARIABILITY)) {
494     vval(VARIABILITY) = "L";
495     vdef(VARIABILITY)++;
496     }
497     }
498    
499    
500     printvals() /* print variable values */
501     {
502     register int i, j;
503    
504     for (i = 0; i < NVARS; i++)
505     for (j = 0; j < vv[i].nass; j++)
506     printf("%s= %s\n", vv[i].name, nvalue(vv+i, j));
507     fflush(stdout);
508     }
509    
510    
511     oconv() /* run oconv if necessary */
512     {
513     char combuf[512], ocopts[64];
514    
515 greg 2.2 if (octreedate >= scenedate) /* check dates */
516 greg 2.1 return;
517     /* build command */
518     oconvopts(ocopts);
519 greg 2.2 sprintf(combuf, "oconv%s %s %s > %s", ocopts,
520     vdef(MATERIAL) ? vval(MATERIAL) : "",
521     vval(SCENE), vval(OCTREE));
522 greg 2.1 if (!silent) { /* echo it */
523     printf("\t%s\n", combuf);
524     fflush(stdout);
525     }
526     if (noaction)
527     return;
528     if (system(combuf)) { /* run it */
529     fprintf(stderr, "%s: error generating octree\n\t%s removed\n",
530     progname, vval(OCTREE));
531     unlink(vval(OCTREE));
532     exit(1);
533     }
534 greg 2.2 octreedate = time(0);
535 greg 2.1 }
536    
537    
538     char *
539     addarg(op, arg) /* add argument and advance pointer */
540     register char *op, *arg;
541     {
542     *op = ' ';
543     while (*++op = *arg++)
544     ;
545     return(op);
546     }
547    
548    
549     oconvopts(oo) /* get oconv options */
550 greg 2.2 register char *oo;
551 greg 2.1 {
552 greg 2.2 /* BEWARE: This may be called via setdefaults(), so no assumptions */
553    
554 greg 2.1 *oo = '\0';
555     if (vdef(OCONV))
556     addarg(oo, vval(OCONV));
557     }
558    
559    
560 greg 2.2 double
561     ambval() /* compute ambient value */
562 greg 2.1 {
563 greg 2.2 if (vdef(EXPOSURE))
564     if (vval(EXPOSURE)[0] == '+' || vval(EXPOSURE)[0] == '-')
565     return(.5/pow(2.,atof(vval(EXPOSURE))));
566     else
567     return(.5/atof(vval(EXPOSURE)));
568     if (vlet(ZONE) == 'E')
569     return(10.);
570     else
571     return(.01);
572     }
573 greg 2.1
574 greg 2.2
575     lowqopts(op) /* low quality rendering options */
576     register char *op;
577     {
578     double d, org[3], siz[3];
579    
580 greg 2.1 *op = '\0';
581 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
582     &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) {
583     fprintf(stderr, "%s: bad value for variable '%s'\n",
584     progname, vnam(ZONE));
585     exit(1);
586     }
587     siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
588     getoctcube(org, &d);
589     d *= 3./(siz[0]+siz[1]+siz[2]);
590     switch (vscale(DETAIL)) {
591     case LOW:
592     op = addarg(op, "-ps 16");
593     op = addarg(op, "-dp 16");
594     sprintf(op, " -ar %d", (int)(4*d));
595     op += strlen(op);
596     break;
597     case MEDIUM:
598     op = addarg(op, "-ps 8");
599     op = addarg(op, "-dp 32");
600     sprintf(op, " -ar %d", (int)(8*d));
601     op += strlen(op);
602     break;
603     case HIGH:
604     op = addarg(op, "-ps 4");
605     op = addarg(op, "-dp 64");
606     sprintf(op, " -ar %d", (int)(16*d));
607     op += strlen(op);
608     break;
609     }
610     op = addarg(op, "-pt .16");
611     if (vbool(PENUMBRAS))
612     op = addarg(op, "-ds .4");
613     op = addarg(op, "-dt .2");
614     op = addarg(op, "-dc .25");
615     op = addarg(op, "-dr 0");
616     op = addarg(op, "-sj 0");
617     op = addarg(op, "-st .7");
618     op = addarg(op, "-ab 0");
619     if (vdef(AMBFILE)) {
620     sprintf(op, " -af %s", vval(AMBFILE));
621     op += strlen(op);
622     } else
623     overture = 0;
624     switch (vscale(VARIABILITY)) {
625     case LOW:
626     op = addarg(op, "-aa .4");
627     op = addarg(op, "-ad 32");
628     break;
629     case MEDIUM:
630     op = addarg(op, "-aa .3");
631     op = addarg(op, "-ad 64");
632     break;
633     case HIGH:
634     op = addarg(op, "-aa .25");
635     op = addarg(op, "-ad 128");
636     break;
637     }
638     op = addarg(op, "-as 0");
639     d = ambval();
640     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
641     op += strlen(op);
642     op = addarg(op, "-lr 3");
643     op = addarg(op, "-lw .02");
644 greg 2.1 if (vdef(RENDER))
645     op = addarg(op, vval(RENDER));
646     }
647    
648    
649 greg 2.2 medqopts(op) /* medium quality rendering options */
650     register char *op;
651 greg 2.1 {
652 greg 2.2 double d, org[3], siz[3];
653 greg 2.1
654     *op = '\0';
655 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
656     &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) {
657     fprintf(stderr, "%s: bad value for variable '%s'\n",
658     progname, vnam(ZONE));
659     exit(1);
660     }
661     siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
662     getoctcube(org, &d);
663     d *= 3./(siz[0]+siz[1]+siz[2]);
664     switch (vscale(DETAIL)) {
665     case LOW:
666     op = addarg(op, vbool(PENUMBRAS) ? "-ps 4" : "-ps 8");
667     op = addarg(op, "-dp 64");
668     sprintf(op, " -ar %d", (int)(8*d));
669     op += strlen(op);
670     break;
671     case MEDIUM:
672     op = addarg(op, vbool(PENUMBRAS) ? "-ps 3" : "-ps 6");
673     op = addarg(op, "-dp 128");
674     sprintf(op, " -ar %d", (int)(16*d));
675     op += strlen(op);
676     break;
677     case HIGH:
678     op = addarg(op, vbool(PENUMBRAS) ? "-ps 2" : "-ps 4");
679     op = addarg(op, "-dp 256");
680     sprintf(op, " -ar %d", (int)(32*d));
681     op += strlen(op);
682     break;
683     }
684     op = addarg(op, "-pt .08");
685     if (vbool(PENUMBRAS)) {
686     op = addarg(op, "-ds .2");
687     op = addarg(op, "-dj .35");
688     } else
689     op = addarg(op, "-ds .3");
690     op = addarg(op, "-dt .1");
691     op = addarg(op, "-dc .5");
692     op = addarg(op, "-dr 1");
693     op = addarg(op, "-sj .7");
694     op = addarg(op, "-st .15");
695     sprintf(op, " -ab %d", overture=vint(INDIRECT));
696     op += strlen(op);
697     if (vdef(AMBFILE)) {
698     sprintf(op, " -af %s", vval(AMBFILE));
699     op += strlen(op);
700     } else
701     overture = 0;
702     switch (vscale(VARIABILITY)) {
703     case LOW:
704     op = addarg(op, "-aa .25");
705     op = addarg(op, "-ad 128");
706     op = addarg(op, "-as 0");
707     break;
708     case MEDIUM:
709     op = addarg(op, "-aa .2");
710     op = addarg(op, "-ad 300");
711     op = addarg(op, "-as 64");
712     break;
713     case HIGH:
714     op = addarg(op, "-aa .15");
715     op = addarg(op, "-ad 500");
716     op = addarg(op, "-as 128");
717     break;
718     }
719     d = ambval();
720     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
721     op += strlen(op);
722     op = addarg(op, "-lr 6");
723     op = addarg(op, "-lw .002");
724 greg 2.1 if (vdef(RENDER))
725     op = addarg(op, vval(RENDER));
726     }
727    
728    
729 greg 2.2 hiqopts(op) /* high quality rendering options */
730     register char *op;
731 greg 2.1 {
732 greg 2.2 double d, org[3], siz[3];
733 greg 2.1
734     *op = '\0';
735 greg 2.2 if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf", &org[0],
736     &siz[0], &org[1], &siz[1], &org[2], &siz[2]) != 6) {
737     fprintf(stderr, "%s: bad value for variable '%s'\n",
738     progname, vnam(ZONE));
739     exit(1);
740     }
741     siz[0] -= org[0]; siz[1] -= org[1]; siz[2] -= org[2];
742     getoctcube(org, &d);
743     d *= 3./(siz[0]+siz[1]+siz[2]);
744     switch (vscale(DETAIL)) {
745     case LOW:
746     op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 8");
747     op = addarg(op, "-dp 256");
748     sprintf(op, " -ar %d", (int)(16*d));
749     op += strlen(op);
750     break;
751     case MEDIUM:
752     op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 5");
753     op = addarg(op, "-dp 512");
754     sprintf(op, " -ar %d", (int)(32*d));
755     op += strlen(op);
756     break;
757     case HIGH:
758     op = addarg(op, vbool(PENUMBRAS) ? "-ps 1" : "-ps 3");
759     op = addarg(op, "-dp 1024");
760     sprintf(op, " -ar %d", (int)(64*d));
761     op += strlen(op);
762     break;
763     }
764     op = addarg(op, "-pt .04");
765     if (vbool(PENUMBRAS)) {
766     op = addarg(op, "-ds .1");
767     op = addarg(op, "-dj .7");
768     } else
769     op = addarg(op, "-ds .2");
770     op = addarg(op, "-dt .05");
771     op = addarg(op, "-dc .75");
772     op = addarg(op, "-dr 3");
773     op = addarg(op, "-sj 1");
774     op = addarg(op, "-st .03");
775     sprintf(op, " -ab %d", overture=vint(INDIRECT)+1);
776     op += strlen(op);
777     if (vdef(AMBFILE)) {
778     sprintf(op, " -af %s", vval(AMBFILE));
779     op += strlen(op);
780     } else
781     overture = 0;
782     switch (vscale(VARIABILITY)) {
783     case LOW:
784     op = addarg(op, "-aa .15");
785     op = addarg(op, "-ad 200");
786     op = addarg(op, "-as 0");
787     break;
788     case MEDIUM:
789     op = addarg(op, "-aa .125");
790     op = addarg(op, "-ad 512");
791     op = addarg(op, "-as 128");
792     break;
793     case HIGH:
794     op = addarg(op, "-aa .08");
795     op = addarg(op, "-ad 850");
796     op = addarg(op, "-as 256");
797     break;
798     }
799     d = ambval();
800     sprintf(op, " -av %.2g %.2g %.2g", d, d, d);
801     op += strlen(op);
802     op = addarg(op, "-lr 12");
803     op = addarg(op, "-lw .0005");
804 greg 2.1 if (vdef(RENDER))
805     op = addarg(op, vval(RENDER));
806     }
807    
808    
809     xferopts(ro) /* transfer options if indicated */
810     char *ro;
811     {
812     int fd, n;
813    
814     n = strlen(ro);
815     if (n < 2)
816     return;
817     if (vdef(OPTFILE)) {
818     if ((fd = open(vval(OPTFILE), O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
819     perror(vval(OPTFILE));
820     exit(1);
821     }
822     if (write(fd, ro+1, n-1) != n-1) {
823     perror(vval(OPTFILE));
824     exit(1);
825     }
826     write(fd, "\n", 1);
827     close(fd);
828     ro[0] = ' ';
829     ro[1] = '^';
830     strcpy(ro+2, vval(OPTFILE));
831     }
832     #ifdef MSDOS
833     else if (n > 50) {
834     register char *evp = bmalloc(n+6);
835     if (evp == NULL) {
836     perror(progname);
837     exit(1);
838     }
839     strcpy(evp, "ROPT=");
840     strcat(evp, ro);
841 greg 2.2 if (putenv(evp) != 0) {
842     fprintf(stderr, "%s: out of environment space\n",
843     progname);
844     exit(1);
845     }
846 greg 2.1 strcpy(ro, " $ROPT");
847     }
848     #endif
849     }
850    
851    
852     pfiltopts(po) /* get pfilt options */
853     register char *po;
854     {
855     *po = '\0';
856     if (vdef(EXPOSURE)) {
857     po = addarg(po, "-1 -e");
858     po = addarg(po, vval(EXPOSURE));
859     }
860     if (vscale(QUALITY) == HIGH)
861     po = addarg(po, "-r .65");
862     if (vdef(PFILT))
863     po = addarg(po, vval(PFILT));
864     }
865    
866    
867     matchword(s1, s2) /* match white-delimited words */
868     register char *s1, *s2;
869     {
870     while (isspace(*s1)) s1++;
871     while (isspace(*s2)) s2++;
872     while (*s1 && !isspace(*s1))
873     if (*s1++ != *s2++)
874     return(0);
875     return(!*s2 || isspace(*s2));
876     }
877    
878    
879     char *
880     specview(vs) /* get proper view spec from vs */
881     register char *vs;
882     {
883     static char viewopts[128];
884     register char *cp;
885     int xpos, ypos, zpos, viewtype;
886     int exterior;
887     double cent[3], dim[3], mult, d;
888    
889     if (vs == NULL || *vs == '-')
890     return(vs);
891     /* check standard view names */
892     xpos = ypos = zpos = 0;
893     viewtype = 0;
894     if (*vs == 'X') {
895     xpos = 1; vs++;
896     } else if (*vs == 'x') {
897     xpos = -1; vs++;
898     }
899     if (*vs == 'Y') {
900     ypos = 1; vs++;
901     } else if (*vs == 'y') {
902     ypos = -1; vs++;
903     }
904     if (*vs == 'Z') {
905     zpos = 1; vs++;
906     } else if (*vs == 'z') {
907     zpos = -1; vs++;
908     }
909     if (*vs == 'v' | *vs == 'l' | *vs == 'a' | *vs == 'h')
910     viewtype = *vs++;
911     else if (!*vs || isspace(*vs))
912     viewtype = 'v';
913     cp = viewopts;
914     if (viewtype && (xpos|ypos|zpos)) { /* got standard view */
915     *cp++ = '-'; *cp++ = 'v'; *cp++ = 't'; *cp++ = viewtype;
916     if (sscanf(vval(ZONE), "%*s %lf %lf %lf %lf %lf %lf",
917     &cent[0], &dim[0], &cent[1], &dim[1],
918     &cent[2], &dim[2]) != 6) {
919     fprintf(stderr, "%s: bad zone specification\n",
920     progname);
921     exit(1);
922     }
923 greg 2.2 dim[0] -= cent[0]; cent[0] += .5*dim[0];
924     dim[1] -= cent[1]; cent[1] += .5*dim[1];
925     dim[2] -= cent[2]; cent[2] += .5*dim[2];
926 greg 2.1 exterior = vlet(ZONE) == 'E';
927     mult = exterior ? 2. : .45 ;
928     sprintf(cp, " -vp %.2g %.2g %.2g -vd %.2g %.2g %.2g",
929     cent[0]+xpos*mult*dim[0],
930     cent[1]+ypos*mult*dim[1],
931     cent[2]+zpos*mult*dim[2],
932     -xpos*dim[0], -ypos*dim[1], -zpos*dim[2]);
933     cp += strlen(cp);
934     switch (vlet(UP)) {
935     case 'Z':
936     if (xpos|ypos) {
937     cp = addarg(cp, "-vu 0 0 1");
938     break;
939     }
940     /* fall through */
941     case 'Y':
942     if (xpos|zpos) {
943     cp = addarg(cp, "-vu 0 1 0");
944     break;
945     }
946     /* fall through */
947     case 'X':
948     if (ypos|zpos)
949     cp = addarg(cp, "-vu 1 0 0");
950     else
951     cp = addarg(cp, "-vu 0 0 1");
952     break;
953     default:
954     fprintf(stderr, "%s: illegal value for variable '%s'\n",
955     progname, vnam(UP));
956     exit(1);
957     }
958     switch (viewtype) {
959     case 'v':
960     cp = addarg(cp, "-vh 45 -vv 45");
961     break;
962     case 'l':
963     d = sqrt(dim[0]*dim[0]+dim[1]*dim[1]+dim[2]*dim[2]);
964     sprintf(cp, " -vh %.2g -vv %.2g", d, d);
965     cp += strlen(cp);
966     break;
967     case 'a':
968     case 'h':
969     cp = addarg(cp, "-vh 180 -vv 180");
970     break;
971     }
972     } else
973     while (*vs && !isspace(*vs)) /* else skip id */
974     vs++;
975     /* append any additional options */
976     while (isspace(*vs)) vs++;
977     strcpy(cp, vs);
978     return(viewopts);
979     }
980    
981    
982     char *
983     getview(n, vn) /* get view n, or NULL if none */
984     int n;
985     char *vn;
986     {
987     register char *mv;
988    
989     if (viewselect != NULL) {
990     if (n) /* only do one */
991     return(NULL);
992     if (viewselect[0] == '-') { /* already specified */
993     if (vn != NULL) *vn = '\0';
994     return(viewselect);
995     }
996     if (vn != NULL) {
997     for (mv = viewselect; *mv && !isspace(*mv);
998     *vn++ = *mv++)
999     ;
1000     *vn = '\0';
1001     }
1002     /* check list */
1003     while ((mv = nvalue(vv+VIEW, n++)) != NULL)
1004     if (matchword(viewselect, mv))
1005     return(specview(mv));
1006     return(specview(viewselect)); /* standard view? */
1007     }
1008     if (vn != NULL && (mv = nvalue(vv+VIEW, n)) != NULL) {
1009     if (*mv != '-')
1010     while (*mv && !isspace(*mv))
1011     *vn++ = *mv++;
1012     *vn = '\0';
1013     }
1014     return(specview(nvalue(vv+VIEW, n))); /* use view n */
1015     }
1016    
1017    
1018     rview(opts) /* run rview with first view */
1019     char *opts;
1020     {
1021     char combuf[512];
1022     /* build command */
1023     sprintf(combuf, "rview %s%s ", getview(0, NULL), opts);
1024     if (rvdevice != NULL)
1025     sprintf(combuf+strlen(combuf), "-o %s ", rvdevice);
1026     strcat(combuf, vval(OCTREE));
1027     if (!silent) { /* echo it */
1028     printf("\t%s\n", combuf);
1029     fflush(stdout);
1030     }
1031     if (noaction)
1032     return;
1033     if (system(combuf)) { /* run it */
1034     fprintf(stderr, "%s: error running rview\n", progname);
1035     exit(1);
1036     }
1037     }
1038    
1039    
1040     rpict(opts) /* run rpict and pfilt for each view */
1041     char *opts;
1042     {
1043 greg 2.2 char combuf[1024];
1044 greg 2.1 char rawfile[MAXPATH], picfile[MAXPATH], rep[MAXPATH], res[32];
1045     char pfopts[64];
1046     char vs[32], *vw;
1047     int vn, mult;
1048     /* get pfilt options */
1049     pfiltopts(pfopts);
1050     /* get resolution, reporting */
1051     mult = vscale(QUALITY)+1;
1052     {
1053     int xres, yres;
1054     double aspect;
1055     int n;
1056     n = sscanf(vval(RESOLUTION), "%d %d %lf", &xres, &yres, &aspect);
1057     if (n == 3)
1058     sprintf(res, "-x %d -y %d -pa %.3f",
1059     mult*xres, mult*yres, aspect);
1060     else if (n) {
1061     if (n == 1) yres = xres;
1062     sprintf(res, "-x %d -y %d", mult*xres, mult*yres);
1063     } else {
1064     fprintf(stderr, "%s: bad value for variable '%s'\n",
1065     progname, vnam(RESOLUTION));
1066     exit(1);
1067     }
1068     }
1069     rep[0] = '\0';
1070     if (vdef(REPORT)) {
1071     double minutes;
1072     int n;
1073     n = sscanf(vval(REPORT), "%lf %s", &minutes, rawfile);
1074     if (n == 2)
1075     sprintf(rep, " -t %d -e %s", (int)(minutes*60), rawfile);
1076     else if (n == 1)
1077     sprintf(rep, " -t %d", (int)(minutes*60));
1078     else {
1079     fprintf(stderr, "%s: bad value for variable '%s'\n",
1080     progname, vnam(REPORT));
1081     exit(1);
1082     }
1083     }
1084     /* do each view */
1085     vn = 0;
1086     while ((vw = getview(vn++, vs)) != NULL) {
1087     if (!vs[0])
1088     sprintf(vs, "%d", vn);
1089     sprintf(picfile, "%s_%s.pic", vval(PICTURE), vs);
1090     /* check date on picture */
1091     if (fdate(picfile) > octreedate)
1092     continue;
1093     /* build rpict command */
1094     sprintf(rawfile, "%s_%s.raw", vval(PICTURE), vs);
1095     if (fdate(rawfile) > octreedate) /* recover */
1096     sprintf(combuf, "rpict%s%s -ro %s %s",
1097     rep, opts, rawfile, vval(OCTREE));
1098     else {
1099     if (overture) { /* run overture calculation */
1100     sprintf(combuf,
1101     "rpict%s %s%s -x 64 -y 64 -ps 1 %s > %s",
1102     rep, vw, opts,
1103     vval(OCTREE), rawfile);
1104     if (!silent) {
1105     printf("\t%s\n", combuf);
1106     fflush(stdout);
1107     }
1108     if (!noaction && system(combuf)) {
1109     fprintf(stderr,
1110     "%s: error in overture for view %s\n\t%s removed\n",
1111     progname, vs, rawfile);
1112     unlink(rawfile);
1113     exit(1);
1114     }
1115     }
1116     sprintf(combuf, "rpict%s %s %s%s %s > %s",
1117     rep, vw, res, opts,
1118     vval(OCTREE), rawfile);
1119     }
1120     if (!silent) { /* echo rpict command */
1121     printf("\t%s\n", combuf);
1122     fflush(stdout);
1123     }
1124     if (!noaction && system(combuf)) { /* run rpict */
1125     fprintf(stderr, "%s: error rendering view %s\n",
1126     progname, vs);
1127     exit(1);
1128     }
1129     /* build pfilt command */
1130     if (mult > 1)
1131     sprintf(combuf, "pfilt%s -x /%d -y /%d %s > %s",
1132     pfopts, mult, mult, rawfile, picfile);
1133     else
1134     sprintf(combuf, "pfilt%s %s > %s", pfopts,
1135     rawfile, picfile);
1136     if (!silent) { /* echo pfilt command */
1137     printf("\t%s\n", combuf);
1138     fflush(stdout);
1139     }
1140     if (!noaction && system(combuf)) { /* run pfilt */
1141     fprintf(stderr,
1142     "%s: error filtering view %s\n\t%s removed\n",
1143     progname, vs, picfile);
1144     unlink(picfile);
1145     exit(1);
1146     }
1147     /* remove raw file */
1148     if (!silent)
1149     #ifdef MSDOS
1150     printf("\tdel %s\n", rawfile);
1151     #else
1152     printf("\trm %s\n", rawfile);
1153     #endif
1154     if (!noaction)
1155     unlink(rawfile);
1156     }
1157     }