ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.25
Committed: Wed Sep 15 15:11:47 1993 UTC (30 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.24: +20 -9 lines
Log Message:
changed setvariable() to squeeze spaces together

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