home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)rmain.c 2.15 11/8/92 LBL";
- #endif
-
- /*
- * rmain.c - main for ray tracing programs
- *
- * 3/24/87
- */
-
- /* for flaky pre-processors */
- #ifndef RPICT
- #define RPICT 0
- #endif
- #ifndef RTRACE
- #define RTRACE 0
- #endif
- #ifndef RVIEW
- #define RVIEW 0
- #endif
-
- #include "ray.h"
-
- #include "resolu.h"
-
- #include "octree.h"
-
- #include <signal.h>
-
- #include "view.h"
-
- #include "paths.h"
-
- char *progname; /* argv[0] */
-
- char *octname; /* octree name */
-
- char *libpath; /* library directory list */
-
- char *sigerr[NSIG]; /* signal error messages */
-
- extern char VersionID[]; /* version ID string */
-
- extern int stderr_v(); /* standard error output */
- int (*errvec)() = stderr_v; /* error output vector */
- int (*wrnvec)() = stderr_v; /* warning output vector */
- int (*cmdvec)() = NULL; /* command error vector */
-
- int (*trace)() = NULL; /* trace call */
- int do_irrad = 0; /* compute irradiance? */
-
- extern long time();
- long tstart; /* start time */
-
- extern int ambnotify(); /* new object notify functions */
- int (*addobjnotify[])() = {ambnotify, NULL};
-
- CUBE thescene; /* our scene */
- OBJECT nsceneobjs; /* number of objects in our scene */
-
- extern int imm_irrad; /* calculate immediate irradiance? */
-
- extern int ralrm; /* seconds between reports */
-
- extern int greyscale; /* map colors to brightness? */
- extern char *devname; /* output device name */
-
- extern char *formstr(); /* string from format */
- extern int inform; /* input format */
- extern int outform; /* output format */
- extern char *outvals; /* output values */
-
- extern VIEW ourview; /* viewing parameters */
-
- extern int hresolu; /* horizontal resolution */
- extern int vresolu; /* vertical resolution */
- extern double pixaspect; /* pixel aspect ratio */
-
- extern int psample; /* pixel sample size */
- extern double maxdiff; /* max. sample difference */
- extern double dstrpix; /* square pixel distribution */
-
- extern double dstrsrc; /* square source distribution */
- extern double shadthresh; /* shadow threshold */
- extern double shadcert; /* shadow testing certainty */
- extern int directrelay; /* number of source relays */
- extern int vspretest; /* virtual source pretest density */
- extern int directinvis; /* light sources invisible to eye? */
- extern double srcsizerat; /* maximum source size/dist. ratio */
-
- extern double specthresh; /* specular sampling threshold */
- extern double specjitter; /* specular sampling jitter */
-
- extern int maxdepth; /* maximum recursion depth */
- extern double minweight; /* minimum ray weight */
-
- extern COLOR ambval; /* ambient value */
- extern double ambacc; /* ambient accuracy */
- extern int ambres; /* ambient resolution */
- extern int ambdiv; /* ambient divisions */
- extern int ambssamp; /* ambient super-samples */
- extern int ambounce; /* ambient bounces */
- extern char *amblist[]; /* ambient include/exclude list */
- extern int ambincl; /* include == 1, exclude == 0 */
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- #define check(ol,al) if (argv[i][ol] || \
- badarg(argc-i-1,argv+i+1,al)) \
- goto badopt
- #define bool(olen,var) switch (argv[i][olen]) { \
- case '\0': var = !var; break; \
- case 'y': case 'Y': case 't': case 'T': \
- case '+': case '1': var = 1; break; \
- case 'n': case 'N': case 'f': case 'F': \
- case '-': case '0': var = 0; break; \
- default: goto badopt; }
- char *err;
- char *recover = NULL;
- char *outfile = NULL;
- char *zfile = NULL;
- char *errfile = NULL;
- char *ambfile = NULL;
- char **amblp = amblist;
- int loadflags = ~IO_FILES;
- int seqstart = 0;
- int rval;
- int i;
- /* record start time */
- tstart = time((long *)0);
- /* global program name */
- progname = argv[0] = fixargv0(argv[0]);
- /* get library path */
- if ((libpath = getenv(ULIBVAR)) == NULL)
- libpath = DEFPATH;
- /* initialize object types */
- initotypes();
- /* initialize urand */
- initurand(2048);
- /* option city */
- for (i = 1; i < argc; i++) {
- /* expand arguments */
- while (rval = expandarg(&argc, &argv, i))
- if (rval < 0) {
- sprintf(errmsg, "cannot expand '%s'", argv[i]);
- error(SYSTEM, errmsg);
- }
- if (argv[i] == NULL || argv[i][0] != '-')
- break; /* break from options */
- if (!strcmp(argv[i], "-version")) {
- puts(VersionID);
- quit(0);
- }
- if (!strcmp(argv[i], "-defaults") ||
- !strcmp(argv[i], "-help")) {
- printdefaults();
- quit(0);
- }
- #if RVIEW
- if (!strcmp(argv[i], "-devices")) {
- printdevices();
- quit(0);
- }
- #endif
- #if RPICT|RVIEW
- rval = getviewopt(&ourview, argc-i, argv+i);
- if (rval >= 0) {
- i += rval;
- continue;
- }
- #endif
- switch (argv[i][1]) {
- #if RPICT|RVIEW
- case 'v': /* view file */
- if (argv[i][2] != 'f')
- goto badopt;
- check(3,"s");
- rval = viewfile(argv[++i], &ourview, NULL);
- if (rval < 0) {
- sprintf(errmsg,
- "cannot open view file \"%s\"",
- argv[i]);
- error(SYSTEM, errmsg);
- } else if (rval == 0) {
- sprintf(errmsg,
- "bad view file \"%s\"",
- argv[i]);
- error(USER, errmsg);
- }
- break;
- #endif
- case 'd': /* direct */
- switch (argv[i][2]) {
- case 't': /* threshold */
- check(3,"f");
- shadthresh = atof(argv[++i]);
- break;
- case 'c': /* certainty */
- check(3,"f");
- shadcert = atof(argv[++i]);
- break;
- case 'j': /* jitter */
- check(3,"f");
- dstrsrc = atof(argv[++i]);
- break;
- case 'r': /* relays */
- check(3,"i");
- directrelay = atoi(argv[++i]);
- break;
- case 'p': /* pretest */
- check(3,"i");
- vspretest = atoi(argv[++i]);
- break;
- case 'i': /* invis. */
- bool(3,directinvis);
- break;
- case 's': /* size */
- check(3,"f");
- srcsizerat = atof(argv[++i]);
- break;
- default:
- goto badopt;
- }
- break;
- case 's': /* specular */
- switch (argv[i][2]) {
- case 't': /* threshold */
- check(3,"f");
- specthresh = atof(argv[++i]);
- break;
- case 'j': /* jitter */
- check(3,"f");
- specjitter = atof(argv[++i]);
- break;
- default:
- goto badopt;
- }
- break;
- #if RPICT|RVIEW
- case 'p': /* pixel */
- switch (argv[i][2]) {
- case 's': /* sample */
- check(3,"i");
- psample = atoi(argv[++i]);
- break;
- case 't': /* threshold */
- check(3,"f");
- maxdiff = atof(argv[++i]);
- break;
- #if RPICT
- case 'j': /* jitter */
- check(3,"f");
- dstrpix = atof(argv[++i]);
- break;
- case 'a': /* aspect */
- check(3,"f");
- pixaspect = atof(argv[++i]);
- break;
- #endif
- default:
- goto badopt;
- }
- break;
- #endif
- #if RPICT|RTRACE
- case 'x': /* x resolution */
- check(2,"i");
- hresolu = atoi(argv[++i]);
- break;
- case 'y': /* y resolution */
- check(2,"i");
- vresolu = atoi(argv[++i]);
- break;
- #endif
- case 'w': /* warnings */
- rval = wrnvec != NULL;
- bool(2,rval);
- if (rval) wrnvec = stderr_v;
- else wrnvec = NULL;
- break;
- case 'e': /* error file */
- check(2,"s");
- errfile = argv[++i];
- break;
- case 'l': /* limit */
- switch (argv[i][2]) {
- case 'r': /* recursion */
- check(3,"i");
- maxdepth = atoi(argv[++i]);
- break;
- case 'w': /* weight */
- check(3,"f");
- minweight = atof(argv[++i]);
- break;
- default:
- goto badopt;
- }
- break;
- case 'i': /* irradiance */
- bool(2,do_irrad);
- break;
- #if RPICT
- case 'S': /* slave index */
- check(2,"i");
- seqstart = atoi(argv[++i]);
- break;
- case 'o': /* output file */
- check(2,"s");
- outfile = argv[++i];
- break;
- case 'z': /* z file */
- check(2,"s");
- zfile = argv[++i];
- break;
- case 'r': /* recover file */
- check(2,"s");
- recover = argv[++i];
- break;
- case 't': /* timer */
- check(2,"i");
- ralrm = atoi(argv[++i]);
- break;
- #endif
- case 'a': /* ambient */
- switch (argv[i][2]) {
- case 'v': /* value */
- check(3,"fff");
- setcolor(ambval, atof(argv[i+1]),
- atof(argv[i+2]),
- atof(argv[i+3]));
- i += 3;
- break;
- case 'a': /* accuracy */
- check(3,"f");
- ambacc = atof(argv[++i]);
- break;
- case 'r': /* resolution */
- check(3,"i");
- ambres = atoi(argv[++i]);
- break;
- case 'd': /* divisions */
- check(3,"i");
- ambdiv = atoi(argv[++i]);
- break;
- case 's': /* super-samp */
- check(3,"i");
- ambssamp = atoi(argv[++i]);
- break;
- case 'b': /* bounces */
- check(3,"i");
- ambounce = atoi(argv[++i]);
- break;
- case 'i': /* include */
- case 'I':
- check(3,"s");
- if (ambincl != 1) {
- ambincl = 1;
- amblp = amblist;
- }
- if (argv[i][2] == 'I') { /* file */
- rval = wordfile(amblp,
- getpath(argv[++i],libpath,R_OK));
- if (rval < 0) {
- sprintf(errmsg,
- "cannot open ambient include file \"%s\"",
- argv[i]);
- error(SYSTEM, errmsg);
- }
- amblp += rval;
- } else
- *amblp++ = argv[++i];
- break;
- case 'e': /* exclude */
- case 'E':
- check(3,"s");
- if (ambincl != 0) {
- ambincl = 0;
- amblp = amblist;
- }
- if (argv[i][2] == 'E') { /* file */
- rval = wordfile(amblp,
- getpath(argv[++i],libpath,R_OK));
- if (rval < 0) {
- sprintf(errmsg,
- "cannot open ambient exclude file \"%s\"",
- argv[i]);
- error(SYSTEM, errmsg);
- }
- amblp += rval;
- } else
- *amblp++ = argv[++i];
- break;
- case 'f': /* file */
- check(3,"s");
- ambfile= argv[++i];
- break;
- default:
- goto badopt;
- }
- break;
- #if RTRACE
- case 'I': /* immed. irradiance */
- bool(2,imm_irrad);
- break;
- case 'f': /* format i/o */
- switch (argv[i][2]) {
- case 'a': /* ascii */
- case 'f': /* float */
- case 'd': /* double */
- inform = argv[i][2];
- break;
- default:
- goto badopt;
- }
- switch (argv[i][3]) {
- case '\0':
- outform = inform;
- break;
- case 'a': /* ascii */
- case 'f': /* float */
- case 'd': /* double */
- case 'c': /* color */
- check(4,"");
- outform = argv[i][3];
- break;
- default:
- goto badopt;
- }
- break;
- case 'o': /* output */
- outvals = argv[i]+2;
- break;
- case 'h': /* header output */
- rval = loadflags & IO_INFO;
- bool(2,rval);
- loadflags = rval ? loadflags | IO_INFO :
- loadflags & ~IO_INFO;
- break;
- #endif
- #if RVIEW
- case 'b': /* black and white */
- bool(2,greyscale);
- break;
- case 'o': /* output device */
- check(2,"s");
- devname = argv[++i];
- break;
- #endif
- default:
- goto badopt;
- }
- }
- *amblp = NULL;
- #if RPICT|RVIEW
- err = setview(&ourview); /* set viewing parameters */
- if (err != NULL)
- error(USER, err);
- #endif
- /* set up signal handling */
- sigdie(SIGINT, "Interrupt");
- sigdie(SIGHUP, "Hangup");
- sigdie(SIGTERM, "Terminate");
- sigdie(SIGPIPE, "Broken pipe");
- sigdie(SIGALRM, "Alarm clock");
- #ifdef SIGXCPU
- sigdie(SIGXCPU, "CPU limit exceeded");
- sigdie(SIGXFSZ, "File size exceeded");
- #endif
- /* open error file */
- if (errfile != NULL) {
- if (freopen(errfile, "a", stderr) == NULL)
- quit(2);
- fprintf(stderr, "**************\n*** PID %5d: ",
- getpid());
- printargs(argc, argv, stderr);
- putc('\n', stderr);
- fflush(stderr);
- }
- #ifdef NICE
- nice(NICE); /* lower priority */
- #endif
- /* get octree */
- #if RVIEW
- loadflags &= ~IO_INFO;
- #endif
- if (i == argc)
- octname = NULL;
- else if (i == argc-1)
- octname = argv[i];
- else
- goto badopt;
- if (
- #if RPICT
- seqstart > 0 &&
- #endif
- octname == NULL)
- error(USER, "missing octree argument");
- #if RPICT
- if (outfile != NULL)
- openheader();
- #endif
- #ifdef MSDOS
- #if RTRACE
- if (outform != 'a')
- #endif
- setmode(fileno(stdout), O_BINARY);
- if (octname == NULL)
- setmode(fileno(stdin), O_BINARY);
- #endif
- readoct(octname, loadflags, &thescene, NULL);
- nsceneobjs = nobjects;
-
- if (loadflags & IO_INFO) { /* print header */
- printargs(i, argv, stdout);
- printf("SOFTWARE= %s\n", VersionID);
- #if RTRACE
- fputformat(formstr(outform), stdout);
- putchar('\n');
- #endif
- }
-
- marksources(); /* find and mark sources */
-
- setambient(ambfile); /* initialize ambient calculation */
-
- #if RPICT
- rpict(seqstart, outfile, zfile, recover);
- #endif
- #if RTRACE
- rtrace(NULL);
- #endif
- #if RVIEW
- rview();
- #endif
- quit(0);
-
- badopt:
- sprintf(errmsg, "command line error at '%s'", argv[i]);
- error(USER, errmsg);
-
- #undef check
- #undef bool
- }
-
-
- eputs(s) /* error output */
- char *s;
- {
- if (errvec != NULL)
- (*errvec)(s);
- }
-
-
- wputs(s) /* warning output */
- char *s;
- {
- int lasterrno = errno; /* save errno */
-
- if (wrnvec != NULL)
- (*wrnvec)(s);
-
- errno = lasterrno;
- }
-
-
- cputs(s) /* command error output */
- char *s;
- {
- if (cmdvec != NULL)
- (*cmdvec)(s);
- }
-
-
- stderr_v(s) /* put string to stderr */
- register char *s;
- {
- static int midline = 0;
-
- if (!*s)
- return;
- if (!midline++) {
- fputs(progname, stderr);
- fputs(": ", stderr);
- }
- fputs(s, stderr);
- if (s[strlen(s)-1] == '\n') {
- fflush(stderr);
- midline = 0;
- }
- }
-
-
- onsig(signo) /* fatal signal */
- int signo;
- {
- static int gotsig = 0;
-
- if (gotsig++) /* two signals and we're gone! */
- _exit(signo);
-
- alarm(15); /* allow 15 seconds to clean up */
- signal(SIGALRM, SIG_DFL); /* make certain we do die */
- eputs("signal - ");
- eputs(sigerr[signo]);
- eputs("\n");
- quit(3);
- }
-
-
- sigdie(signo, msg) /* set fatal signal */
- int signo;
- char *msg;
- {
- if (signal(signo, onsig) == SIG_IGN)
- signal(signo, SIG_IGN);
- sigerr[signo] = msg;
- }
-
-
- printdefaults() /* print default values to stdout */
- {
- register char *cp;
-
- #if RTRACE
- if (imm_irrad)
- printf("-I+\t\t\t\t# immediate irradiance on\n");
- else
- #endif
- printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
- "-i-\t\t\t\t# irradiance calculation off\n");
- #if RVIEW
- printf(greyscale ? "-b+\t\t\t\t# greyscale on\n" :
- "-b-\t\t\t\t# greyscale off\n");
- #endif
- #if RPICT|RVIEW
- printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
- ourview.type==VT_PER ? "perspective" :
- ourview.type==VT_PAR ? "parallel" :
- ourview.type==VT_HEM ? "hemispherical" :
- ourview.type==VT_ANG ? "angular" :
- "unknown");
- printf("-vp %f %f %f\t# view point\n",
- ourview.vp[0], ourview.vp[1], ourview.vp[2]);
- printf("-vd %f %f %f\t# view direction\n",
- ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
- printf("-vu %f %f %f\t# view up\n",
- ourview.vup[0], ourview.vup[1], ourview.vup[2]);
- printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
- printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
- printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
- printf("-vl %f\t\t\t# view lift\n", ourview.voff);
- #endif
- #if RPICT|RTRACE
- printf("-x %-9d\t\t\t# x resolution\n", hresolu);
- printf("-y %-9d\t\t\t# y resolution\n", vresolu);
- #endif
- #if RPICT
- printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
- printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
- #endif
- #if RPICT|RVIEW
- printf("-ps %-9d\t\t\t# pixel sample\n", psample);
- printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
- #endif
- printf("-dt %f\t\t\t# direct threshold\n", shadthresh);
- printf("-dc %f\t\t\t# direct certainty\n", shadcert);
- printf("-dj %f\t\t\t# direct jitter\n", dstrsrc);
- printf("-ds %f\t\t\t# direct sampling\n", srcsizerat);
- printf("-dr %-9d\t\t\t# direct relays\n", directrelay);
- printf("-dp %-9d\t\t\t# direct pretest density\n", vspretest);
- printf(directinvis ? "-di+\t\t\t\t# direct invisibility on\n" :
- "-di-\t\t\t\t# direct invisibility off\n");
- printf("-sj %f\t\t\t# specular jitter\n", specjitter);
- printf("-st %f\t\t\t# specular threshold\n", specthresh);
- printf("-av %f %f %f\t# ambient value\n", colval(ambval,RED),
- colval(ambval,GRN), colval(ambval, BLU));
- printf("-ab %-9d\t\t\t# ambient bounces\n", ambounce);
- printf("-aa %f\t\t\t# ambient accuracy\n", ambacc);
- printf("-ar %-9d\t\t\t# ambient resolution\n", ambres);
- printf("-ad %-9d\t\t\t# ambient divisions\n", ambdiv);
- printf("-as %-9d\t\t\t# ambient super-samples\n", ambssamp);
- printf("-lr %-9d\t\t\t# limit reflection\n", maxdepth);
- printf("-lw %f\t\t\t# limit weight\n", minweight);
- #if RPICT
- printf("-t %-9d\t\t\t# time between reports\n", ralrm);
- #endif
- #if RVIEW
- printf("-o %s\t\t\t\t# output device\n", devname);
- #endif
- #if RTRACE
- printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
- inform, outform, formstr(inform), formstr(outform));
- printf("-o%s\t\t\t\t# output", outvals);
- for (cp = outvals; *cp; cp++)
- switch (*cp) {
- case 't': printf(" trace"); break;
- case 'o': printf(" origin"); break;
- case 'd': printf(" direction"); break;
- case 'v': printf(" value"); break;
- case 'l': printf(" length"); break;
- case 'L': printf(" first_length"); break;
- case 'p': printf(" point"); break;
- case 'n': printf(" normal"); break;
- case 'N': printf(" unperturbed_normal"); break;
- case 's': printf(" surface"); break;
- case 'w': printf(" weight"); break;
- case 'm': printf(" modifier"); break;
- }
- putchar('\n');
- #endif
- printf(wrnvec != NULL ? "-w+\t\t\t\t# warning messages on\n" :
- "-w-\t\t\t\t# warning messages off\n");
- }
-