ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rad.c
Revision: 2.24
Committed: Thu Sep 9 13:07:13 1993 UTC (30 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.23: +13 -3 lines
Log Message:
fixed view echoing for MS-DOS

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