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

# Content
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 extern long fdate(), time();
96
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 do
345 vp->value += strlen(vp->value)+1;
346 while (--vp->nass > 1);
347 }
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 char *cp;
392 long objdate;
393
394 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 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 fprintf(stderr, "%s: need '%s' or '%s'\n", progname,
415 vnam(OCTREE), vnam(SCENE));
416 exit(1);
417 }
418 }
419
420
421 getoctcube(org, sizp) /* get octree bounding cube */
422 double org[3], *sizp;
423 {
424 extern FILE *popen();
425 static double oorg[3], osiz = 0.;
426 char buf[MAXPATH+16];
427 FILE *fp;
428
429 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 }
445 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 if (!vdef(ZONE)) {
455 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 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 if (octreedate >= scenedate) /* check dates */
516 return;
517 /* build command */
518 oconvopts(ocopts);
519 sprintf(combuf, "oconv%s %s %s > %s", ocopts,
520 vdef(MATERIAL) ? vval(MATERIAL) : "",
521 vval(SCENE), vval(OCTREE));
522 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 octreedate = time(0);
535 }
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 register char *oo;
551 {
552 /* BEWARE: This may be called via setdefaults(), so no assumptions */
553
554 *oo = '\0';
555 if (vdef(OCONV))
556 addarg(oo, vval(OCONV));
557 }
558
559
560 double
561 ambval() /* compute ambient value */
562 {
563 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
574
575 lowqopts(op) /* low quality rendering options */
576 register char *op;
577 {
578 double d, org[3], siz[3];
579
580 *op = '\0';
581 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 if (vdef(RENDER))
645 op = addarg(op, vval(RENDER));
646 }
647
648
649 medqopts(op) /* medium quality rendering options */
650 register char *op;
651 {
652 double d, org[3], siz[3];
653
654 *op = '\0';
655 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 if (vdef(RENDER))
725 op = addarg(op, vval(RENDER));
726 }
727
728
729 hiqopts(op) /* high quality rendering options */
730 register char *op;
731 {
732 double d, org[3], siz[3];
733
734 *op = '\0';
735 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 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 if (putenv(evp) != 0) {
842 fprintf(stderr, "%s: out of environment space\n",
843 progname);
844 exit(1);
845 }
846 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 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 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 char combuf[1024];
1044 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 }