ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rmain.c
Revision: 1.43
Committed: Fri Jul 19 15:08:33 1991 UTC (33 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.42: +25 -10 lines
Log Message:
added explicit boolean option switching and reporting

File Contents

# User Rev Content
1 greg 1.34 /* Copyright (c) 1991 Regents of the University of California */
2 greg 1.1
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * rmain.c - main for ray tracing programs
9     *
10     * 3/24/87
11     */
12    
13     /* for flaky pre-processors */
14     #ifndef RPICT
15     #define RPICT 0
16     #endif
17     #ifndef RTRACE
18     #define RTRACE 0
19     #endif
20     #ifndef RVIEW
21     #define RVIEW 0
22     #endif
23    
24     #include "ray.h"
25    
26     #include "octree.h"
27    
28     #include <signal.h>
29    
30     #include "view.h"
31    
32     #ifndef DEFPATH
33     #define DEFPATH ":/usr/local/lib/ray"
34     #endif
35 greg 1.17 #ifndef ULIBVAR
36 greg 1.1 #define ULIBVAR "RAYPATH"
37 greg 1.17 #endif
38 greg 1.1
39     char *progname; /* argv[0] */
40    
41 greg 1.19 char *octname; /* octree name */
42    
43 greg 1.1 char *libpath; /* library directory list */
44    
45     char *sigerr[NSIG]; /* signal error messages */
46    
47     extern int stderr_v(); /* standard error output */
48     int (*errvec)() = stderr_v; /* error output vector */
49     int (*wrnvec)() = stderr_v; /* warning output vector */
50     int (*cmdvec)() = NULL; /* command error vector */
51    
52     int (*trace)() = NULL; /* trace call */
53 greg 1.36 int do_irrad = 0; /* compute irradiance? */
54 greg 1.1
55 greg 1.34 extern long time();
56     long tstart; /* start time */
57    
58 greg 1.24 extern int ambnotify(); /* new object notify functions */
59     int (*addobjnotify[])() = {ambnotify, NULL};
60    
61 greg 1.1 CUBE thescene; /* our scene */
62    
63 greg 1.36 extern int imm_irrad; /* calculate immediate irradiance? */
64    
65 greg 1.1 extern int ralrm; /* seconds between reports */
66    
67     extern int greyscale; /* map colors to brightness? */
68     extern char *devname; /* output device name */
69    
70     extern int inform; /* input format */
71     extern int outform; /* output format */
72     extern char *outvals; /* output values */
73    
74     extern VIEW ourview; /* viewing parameters */
75    
76     extern int hresolu; /* horizontal resolution */
77     extern int vresolu; /* vertical resolution */
78 greg 1.22 extern double pixaspect; /* pixel aspect ratio */
79 greg 1.1
80     extern int psample; /* pixel sample size */
81     extern double maxdiff; /* max. sample difference */
82 greg 1.11 extern double dstrpix; /* square pixel distribution */
83 greg 1.1
84     extern double dstrsrc; /* square source distribution */
85 greg 1.11 extern double shadthresh; /* shadow threshold */
86 greg 1.15 extern double shadcert; /* shadow testing certainty */
87 greg 1.39 extern int directrelay; /* number of source relays */
88 greg 1.40 extern int vspretest; /* virtual source pretest density */
89 greg 1.42 extern int directinvis; /* light sources invisible to eye? */
90 greg 1.1
91     extern int maxdepth; /* maximum recursion depth */
92     extern double minweight; /* minimum ray weight */
93    
94     extern COLOR ambval; /* ambient value */
95     extern double ambacc; /* ambient accuracy */
96     extern int ambres; /* ambient resolution */
97     extern int ambdiv; /* ambient divisions */
98     extern int ambssamp; /* ambient super-samples */
99     extern int ambounce; /* ambient bounces */
100     extern char *amblist[]; /* ambient include/exclude list */
101     extern int ambincl; /* include == 1, exclude == 0 */
102    
103    
104     main(argc, argv)
105     int argc;
106     char *argv[];
107     {
108 greg 1.16 #define check(olen,narg) if (argv[i][olen] || narg >= argc-i) goto badopt
109 greg 1.43 #define bool(olen,var) switch (argv[i][olen]) { \
110     case '\0': var = !var; break; \
111     case 'y': case 'Y': case 't': case 'T': \
112     case '+': case '1': var = 1; break; \
113     case 'n': case 'N': case 'f': case 'F': \
114     case '-': case '0': var = 0; break; \
115     default: goto badopt; }
116 greg 1.1 double atof();
117     char *getenv();
118     int report();
119     char *err;
120     char *recover = NULL;
121 greg 1.20 char *zfile = NULL;
122 greg 1.1 char *errfile = NULL;
123     char *ambfile = NULL;
124     char **amblp = amblist;
125     int loadflags = ~IO_FILES;
126 greg 1.4 int rval, gotvfile = 0;
127 greg 1.1 int i;
128 greg 1.34 /* record start time */
129     tstart = time((long *)0);
130 greg 1.1 /* global program name */
131     progname = argv[0];
132     /* get library path */
133     if ((libpath = getenv(ULIBVAR)) == NULL)
134     libpath = DEFPATH;
135 greg 1.31 /* initialize object types */
136     initotypes();
137 greg 1.37 /* initialize urand */
138 greg 1.41 initurand(2048);
139 greg 1.10 /* option city */
140 greg 1.1 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
141 greg 1.18 if (!strcmp(argv[i], "-defaults") ||
142     !strcmp(argv[i], "-help")) {
143 greg 1.1 printdefaults();
144     quit(0);
145     }
146     #if RVIEW
147     if (!strcmp(argv[i], "-devices")) {
148     printdevices();
149     quit(0);
150     }
151     #endif
152 greg 1.21 #if RPICT|RVIEW
153     rval = getviewopt(&ourview, argc-i, argv+i);
154     if (rval >= 0) {
155     i += rval;
156     continue;
157     }
158     #endif
159 greg 1.1 switch (argv[i][1]) {
160     #if RPICT|RVIEW
161 greg 1.21 case 'v': /* view file */
162     if (argv[i][2] != 'f')
163 greg 1.10 goto badopt;
164 greg 1.21 check(3,1);
165 greg 1.25 rval = viewfile(argv[++i], &ourview, 0, 0);
166 greg 1.21 if (rval < 0) {
167     sprintf(errmsg,
168     "cannot open view file \"%s\"",
169     argv[i]);
170     error(SYSTEM, errmsg);
171     } else if (rval == 0) {
172     sprintf(errmsg,
173     "bad view file \"%s\"",
174     argv[i]);
175     error(USER, errmsg);
176     } else
177     gotvfile += rval;
178 greg 1.1 break;
179     #endif
180 greg 1.11 case 'd': /* direct */
181 greg 1.1 switch (argv[i][2]) {
182 greg 1.13 case 't': /* threshold */
183 greg 1.10 check(3,1);
184 greg 1.11 shadthresh = atof(argv[++i]);
185 greg 1.1 break;
186 greg 1.15 case 'c': /* certainty */
187     check(3,1);
188     shadcert = atof(argv[++i]);
189     break;
190 greg 1.11 case 'j': /* jitter */
191 greg 1.10 check(3,1);
192 greg 1.1 dstrsrc = atof(argv[++i]);
193     break;
194 greg 1.39 case 'r':
195     check(3,1);
196     directrelay = atoi(argv[++i]);
197     break;
198 greg 1.40 case 'p':
199     check(3,1);
200     vspretest = atoi(argv[++i]);
201 greg 1.42 break;
202     case 'i':
203 greg 1.43 bool(3,directinvis);
204 greg 1.40 break;
205 greg 1.1 default:
206 greg 1.10 goto badopt;
207 greg 1.1 }
208     break;
209     #if RPICT|RVIEW
210     case 's': /* sample */
211     switch (argv[i][2]) {
212     case 'p': /* pixel */
213 greg 1.10 check(3,1);
214 greg 1.1 psample = atoi(argv[++i]);
215     break;
216 greg 1.13 case 't': /* threshold */
217 greg 1.10 check(3,1);
218 greg 1.1 maxdiff = atof(argv[++i]);
219     break;
220 greg 1.11 #if RPICT
221     case 'j': /* jitter */
222     check(3,1);
223     dstrpix = atof(argv[++i]);
224     break;
225     #endif
226 greg 1.1 default:
227 greg 1.10 goto badopt;
228 greg 1.1 }
229     break;
230     #endif
231 greg 1.22 #if RPICT|RTRACE
232 greg 1.1 case 'x': /* x resolution */
233 greg 1.10 check(2,1);
234 greg 1.1 hresolu = atoi(argv[++i]);
235     break;
236     case 'y': /* y resolution */
237 greg 1.10 check(2,1);
238 greg 1.1 vresolu = atoi(argv[++i]);
239     break;
240 greg 1.22 #endif
241     #if RPICT
242     case 'p': /* pixel aspect */
243 greg 1.23 check(2,1);
244 greg 1.22 pixaspect = atof(argv[++i]);
245     break;
246     #endif
247 greg 1.1 case 'w': /* warnings */
248 greg 1.43 rval = wrnvec != NULL;
249     bool(2,rval);
250     wrnvec = rval ? stderr_v : NULL;
251 greg 1.1 break;
252     case 'e': /* error file */
253 greg 1.10 check(2,1);
254 greg 1.1 errfile = argv[++i];
255     break;
256     case 'l': /* limit */
257     switch (argv[i][2]) {
258     case 'r': /* recursion */
259 greg 1.10 check(3,1);
260 greg 1.1 maxdepth = atoi(argv[++i]);
261     break;
262     case 'w': /* weight */
263 greg 1.10 check(3,1);
264 greg 1.1 minweight = atof(argv[++i]);
265     break;
266     default:
267 greg 1.10 goto badopt;
268 greg 1.1 }
269     break;
270 greg 1.36 case 'i': /* irradiance */
271 greg 1.43 bool(2,do_irrad);
272 greg 1.36 break;
273 greg 1.1 #if RPICT
274 greg 1.20 case 'z': /* z file */
275     check(2,1);
276     zfile = argv[++i];
277     break;
278 greg 1.1 case 'r': /* recover file */
279 greg 1.10 check(2,1);
280 greg 1.1 recover = argv[++i];
281 greg 1.25 rval = viewfile(recover, &ourview, &hresolu, &vresolu);
282 greg 1.5 if (rval <= 0) {
283     sprintf(errmsg,
284     "cannot recover view parameters from \"%s\"", recover);
285     error(WARNING, errmsg);
286 greg 1.25 } else {
287 greg 1.4 gotvfile += rval;
288 greg 1.25 pixaspect = 0.0;
289     }
290 greg 1.1 break;
291     case 't': /* timer */
292 greg 1.10 check(2,1);
293 greg 1.1 ralrm = atoi(argv[++i]);
294     break;
295     #endif
296     case 'a': /* ambient */
297     switch (argv[i][2]) {
298     case 'v': /* value */
299 greg 1.10 check(3,3);
300 greg 1.1 setcolor(ambval, atof(argv[i+1]),
301     atof(argv[i+2]),
302     atof(argv[i+3]));
303     i += 3;
304     break;
305     case 'a': /* accuracy */
306 greg 1.10 check(3,1);
307 greg 1.1 ambacc = atof(argv[++i]);
308     break;
309     case 'r': /* resolution */
310 greg 1.10 check(3,1);
311 greg 1.1 ambres = atoi(argv[++i]);
312     break;
313     case 'd': /* divisions */
314 greg 1.10 check(3,1);
315 greg 1.1 ambdiv = atoi(argv[++i]);
316     break;
317     case 's': /* super-samp */
318 greg 1.10 check(3,1);
319 greg 1.1 ambssamp = atoi(argv[++i]);
320     break;
321     case 'b': /* bounces */
322 greg 1.10 check(3,1);
323 greg 1.1 ambounce = atoi(argv[++i]);
324     break;
325     case 'i': /* include */
326 greg 1.10 check(3,1);
327 greg 1.1 if (ambincl != 1) {
328     ambincl = 1;
329     amblp = amblist;
330     }
331     *amblp++ = argv[++i];
332     break;
333     case 'e': /* exclude */
334 greg 1.10 check(3,1);
335 greg 1.1 if (ambincl != 0) {
336     ambincl = 0;
337     amblp = amblist;
338     }
339     *amblp++ = argv[++i];
340     break;
341     case 'f': /* file */
342 greg 1.10 check(3,1);
343 greg 1.1 ambfile= argv[++i];
344     break;
345     default:
346 greg 1.10 goto badopt;
347 greg 1.1 }
348     break;
349     #if RTRACE
350 greg 1.36 case 'I': /* immed. irradiance */
351 greg 1.43 bool(2,imm_irrad);
352 greg 1.36 break;
353 greg 1.1 case 'f': /* format i/o */
354     switch (argv[i][2]) {
355     case 'a': /* ascii */
356     case 'f': /* float */
357     case 'd': /* double */
358     inform = argv[i][2];
359     break;
360     default:
361 greg 1.10 goto badopt;
362 greg 1.1 }
363     switch (argv[i][3]) {
364     case '\0':
365     outform = inform;
366     break;
367     case 'a': /* ascii */
368     case 'f': /* float */
369     case 'd': /* double */
370 greg 1.12 check(4,0);
371 greg 1.1 outform = argv[i][3];
372     break;
373     default:
374 greg 1.10 goto badopt;
375 greg 1.1 }
376     break;
377     case 'o': /* output */
378     outvals = argv[i]+2;
379     break;
380 greg 1.6 case 'h': /* toggle header */
381 greg 1.10 check(2,0);
382 greg 1.6 loadflags ^= IO_INFO;
383 greg 1.1 break;
384     #endif
385     #if RVIEW
386     case 'b': /* black and white */
387 greg 1.10 check(2,0);
388 greg 1.1 greyscale = !greyscale;
389     break;
390     case 'o': /* output device */
391 greg 1.10 check(2,1);
392 greg 1.1 devname = argv[++i];
393     break;
394     #endif
395     default:
396 greg 1.19 goto badopt;
397 greg 1.1 }
398     }
399 greg 1.24 *amblp = NULL;
400 greg 1.1 #if RPICT|RVIEW
401     err = setview(&ourview); /* set viewing parameters */
402     if (err != NULL)
403     error(USER, err);
404     #endif
405 greg 1.22 #if RPICT
406 greg 1.23 normaspect(viewaspect(&ourview), &pixaspect, &hresolu, &vresolu);
407 greg 1.22 #endif
408 greg 1.1 /* set up signal handling */
409     sigdie(SIGINT, "Interrupt");
410     sigdie(SIGHUP, "Hangup");
411     sigdie(SIGTERM, "Terminate");
412     sigdie(SIGPIPE, "Broken pipe");
413     #ifdef SIGXCPU
414     sigdie(SIGXCPU, "CPU limit exceeded");
415     sigdie(SIGXFSZ, "File size exceeded");
416     #endif
417     #if RPICT
418     signal(SIGALRM, report);
419     #else
420     sigdie(SIGALRM, "Alarm clock");
421     #endif
422     /* open error file */
423     if (errfile != NULL) {
424     if (freopen(errfile, "a", stderr) == NULL)
425 greg 1.14 quit(2);
426 greg 1.1 fprintf(stderr, "**************\n*** PID %5d: ",
427     getpid());
428     printargs(argc, argv, stderr);
429     fputs("\n", stderr);
430     fflush(stderr);
431     }
432     #ifdef NICE
433     nice(NICE); /* lower priority */
434     #endif
435 greg 1.19 /* get octree */
436 greg 1.1 #if RVIEW
437     loadflags &= ~IO_INFO;
438     #endif
439     if (i == argc)
440 greg 1.19 octname = NULL;
441     else if (i == argc-1)
442     octname = argv[i];
443 greg 1.1 else
444 greg 1.19 goto badopt;
445     #if RVIEW|RTRACE
446     if (octname == NULL)
447     error(USER, "missing octree argument");
448 greg 1.1 #endif
449 greg 1.19 readoct(octname, loadflags, &thescene, NULL);
450 greg 1.1
451     if (loadflags & IO_INFO) { /* print header */
452     printargs(i, argv, stdout);
453     #if RPICT
454     if (gotvfile) {
455     printf(VIEWSTR);
456     fprintview(&ourview, stdout);
457     printf("\n");
458     }
459 greg 1.23 if (pixaspect < .99 || pixaspect > 1.01)
460 greg 1.22 fputaspect(pixaspect, stdout);
461 greg 1.35 fputformat(COLRFMT, stdout);
462     #endif
463     #if RTRACE
464     fputformat( outform=='a' ? "ascii" :
465     outform=='f' ? "float" :
466     "double", stdout );
467 greg 1.1 #endif
468     printf("\n");
469     }
470    
471     marksources(); /* find and mark sources */
472    
473 greg 1.24 setambient(ambfile); /* initialize ambient calculation */
474 greg 1.1
475     #if RPICT
476 greg 1.20 render(zfile, recover); /* render the scene */
477 greg 1.1 #endif
478     #if RTRACE
479     rtrace(NULL); /* trace rays from stdin */
480     #endif
481     #if RVIEW
482     rview(); /* go */
483     #endif
484     quit(0);
485 greg 1.19
486     badopt:
487     sprintf(errmsg, "command line error at '%s'", argv[i]);
488     error(USER, errmsg);
489    
490 greg 1.10 #undef check
491 greg 1.43 #undef bool
492 greg 1.1 }
493    
494    
495     eputs(s) /* error output */
496     char *s;
497     {
498     if (errvec != NULL)
499     (*errvec)(s);
500     }
501    
502    
503     wputs(s) /* warning output */
504     char *s;
505     {
506     if (wrnvec != NULL)
507     (*wrnvec)(s);
508     }
509    
510    
511     cputs(s) /* command error output */
512     char *s;
513     {
514     if (cmdvec != NULL)
515     (*cmdvec)(s);
516     }
517    
518    
519     stderr_v(s) /* put string to stderr */
520     register char *s;
521     {
522 greg 1.26 static int midline = 0;
523 greg 1.1
524 greg 1.27 if (!*s)
525     return;
526 greg 1.26 if (!midline++) {
527 greg 1.1 fputs(progname, stderr);
528     fputs(": ", stderr);
529     }
530     fputs(s, stderr);
531 greg 1.27 if (s[strlen(s)-1] == '\n') {
532 greg 1.1 fflush(stderr);
533 greg 1.26 midline = 0;
534 greg 1.1 }
535     }
536    
537    
538     onsig(signo) /* fatal signal */
539     int signo;
540     {
541 greg 1.8 static int gotsig = 0;
542    
543     if (gotsig++) /* two signals and we're gone! */
544 greg 1.9 _exit(signo);
545 greg 1.8
546 greg 1.1 eputs("signal - ");
547     eputs(sigerr[signo]);
548     eputs("\n");
549 greg 1.14 quit(3);
550 greg 1.1 }
551    
552    
553     sigdie(signo, msg) /* set fatal signal */
554     int signo;
555     char *msg;
556     {
557     if (signal(signo, onsig) == SIG_IGN)
558     signal(signo, SIG_IGN);
559     sigerr[signo] = msg;
560     }
561    
562    
563     printdefaults() /* print default values to stdout */
564     {
565     register char *cp;
566    
567 greg 1.43 #if RTRACE
568     if (imm_irrad)
569     printf("-I+\t\t\t\t# immediate irradiance on\n");
570     else
571     #endif
572     printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
573     "-i-\t\t\t\t# irradiance calculation off\n");
574 greg 1.1 #if RPICT|RVIEW
575 greg 1.7 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
576 greg 1.1 ourview.type==VT_PER ? "perspective" :
577     ourview.type==VT_PAR ? "parallel" :
578 greg 1.28 ourview.type==VT_HEM ? "hemispherical" :
579     ourview.type==VT_ANG ? "angular" :
580 greg 1.1 "unknown");
581     printf("-vp %f %f %f\t# view point\n",
582     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
583     printf("-vd %f %f %f\t# view direction\n",
584     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
585     printf("-vu %f %f %f\t# view up\n",
586     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
587     printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
588     printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
589 greg 1.22 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
590     printf("-vl %f\t\t\t# view lift\n", ourview.voff);
591 greg 1.1 #endif
592 greg 1.22 #if RPICT|RTRACE
593 greg 1.1 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
594     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
595 greg 1.22 #endif
596     #if RPICT
597 greg 1.23 printf("-p %f\t\t\t# pixel aspect ratio\n", pixaspect);
598 greg 1.22 #endif
599 greg 1.1 #if RPICT|RVIEW
600     printf("-sp %-9d\t\t\t# sample pixel\n", psample);
601 greg 1.13 printf("-st %f\t\t\t# sample threshold\n", maxdiff);
602 greg 1.22 #endif
603 greg 1.11 #if RPICT
604     printf("-sj %f\t\t\t# sample jitter\n", dstrpix);
605 greg 1.1 #endif
606 greg 1.29 printf("-dt %f\t\t\t# direct threshold\n", shadthresh);
607     printf("-dc %f\t\t\t# direct certainty\n", shadcert);
608     printf("-dj %f\t\t\t# direct jitter\n", dstrsrc);
609 greg 1.39 printf("-dr %-9d\t\t\t# direct relays\n", directrelay);
610 greg 1.40 printf("-dp %-9d\t\t\t# direct pretest density\n", vspretest);
611 greg 1.43 printf(directinvis ? "-di+\t\t\t\t# direct invisibility on\n" :
612     "-di-\t\t\t\t# direct invisibility off\n");
613 greg 1.1 printf("-av %f %f %f\t# ambient value\n", colval(ambval,RED),
614     colval(ambval,GRN), colval(ambval, BLU));
615     printf("-ab %-9d\t\t\t# ambient bounces\n", ambounce);
616     printf("-aa %f\t\t\t# ambient accuracy\n", ambacc);
617     printf("-ar %-9d\t\t\t# ambient resolution\n", ambres);
618     printf("-ad %-9d\t\t\t# ambient divisions\n", ambdiv);
619     printf("-as %-9d\t\t\t# ambient super-samples\n", ambssamp);
620     printf("-lr %-9d\t\t\t# limit reflection\n", maxdepth);
621     printf("-lw %f\t\t\t# limit weight\n", minweight);
622     #if RPICT
623     printf("-t %-9d\t\t\t# time between reports\n", ralrm);
624     #endif
625     #if RVIEW
626     printf("-o %s\t\t\t\t# output device\n", devname);
627     #endif
628     #if RTRACE
629     printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
630     inform, outform,
631     inform=='a' ? "ascii" :
632     inform=='f' ? "float" : "double",
633     outform=='a' ? "ascii" :
634     outform=='f' ? "float" : "double");
635     printf("-o%s\t\t\t\t# output", outvals);
636     for (cp = outvals; *cp; cp++)
637     switch (*cp) {
638     case 't': printf(" trace"); break;
639     case 'o': printf(" origin"); break;
640     case 'd': printf(" direction"); break;
641     case 'v': printf(" value"); break;
642     case 'l': printf(" length"); break;
643     case 'p': printf(" point"); break;
644     case 'n': printf(" normal"); break;
645     case 's': printf(" surface"); break;
646     case 'w': printf(" weight"); break;
647     case 'm': printf(" modifier"); break;
648     }
649     printf("\n");
650     #endif
651 greg 1.43 printf(wrnvec != NULL ? "-w+\t\t\t\t# warning messages on\n" :
652     "-w-\t\t\t\t# warning messages off\n");
653 greg 1.1 }