home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1991 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)mkillum.c 2.4 7/21/92 LBL";
- #endif
-
- /*
- * Make illum sources for optimizing rendering process
- */
-
- #include "mkillum.h"
-
- #include <signal.h>
-
- #include <ctype.h>
-
- /* default parameters */
- #define SAMPDENS 48 /* points per projected steradian */
- #define NSAMPS 32 /* samples per point */
- #define DFLMAT "illum_mat" /* material name */
- #define DFLDAT "illum" /* data file name */
- /* selection options */
- #define S_NONE 0 /* select none */
- #define S_ELEM 1 /* select specified element */
- #define S_COMPL 2 /* select all but element */
- #define S_ALL 3 /* select all */
-
- /* rtrace command and defaults */
- char *rtargv[64] = { "rtrace", "-dj", ".25", "-dr", "3", "-di+",
- "-ab", "2", "-ad", "256", "-as", "128", "-aa", ".15", };
- int rtargc = 14;
- /* overriding rtrace options */
- char *myrtopts[] = { "-I-", "-i-", "-ov", "-h-", "-fff", "-y", "0", NULL };
-
- struct rtproc rt; /* our rtrace process */
-
- struct illum_args thisillum = { /* our illum and default values */
- 0,
- DFLMAT,
- DFLDAT,
- 0,
- VOIDID,
- SAMPDENS,
- NSAMPS,
- 0.,
- };
-
- char matcheck[MAXSTR]; /* current material to include or exclude */
- int matselect = S_ALL; /* selection criterion */
-
- FUN ofun[NUMOTYPE] = INIT_OTYPE; /* object types */
-
- int gargc; /* global argc */
- char **gargv; /* global argv */
- #define progname gargv[0]
-
- int doneheader = 0; /* printed header yet? */
- #define checkhead() if (!doneheader++) printhead(gargc,gargv)
-
- int warnings = 1; /* print warnings? */
-
- extern char *fgetline(), *fgetword(), *sskip(),
- *atos(), *iskip(), *fskip(), *strcpy();
- extern FILE *popen();
-
-
- main(argc, argv) /* compute illum distributions using rtrace */
- int argc;
- char *argv[];
- {
- extern char *getenv(), *getpath();
- char *rtpath;
- FILE *fp;
- register int i;
- /* set global arguments */
- gargv = argv;
- /* set up rtrace command */
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '<' && !argv[i][1])
- break;
- rtargv[rtargc++] = argv[i];
- if (argv[i][0] == '-' && argv[i][1] == 'w')
- warnings = !warnings;
- }
- gargc = i;
- rtargc--;
- for (i = 0; myrtopts[i] != NULL; i++)
- rtargv[rtargc++] = myrtopts[i];
- rtargv[rtargc++] = argv[gargc-1];
- rtargv[rtargc] = NULL;
- /* just asking for defaults? */
- if (!strcmp(argv[gargc-1], "-defaults")) {
- printopts(); fflush(stdout);
- rtpath = getpath(rtargv[0], getenv("PATH"), X_OK);
- if (rtpath == NULL) {
- eputs(rtargv[0]);
- eputs(": command not found\n");
- exit(1);
- }
- execv(rtpath, rtargv);
- perror(rtpath);
- exit(1);
- }
- if (gargc < 2 || argv[gargc-1][0] == '-')
- error(USER, "missing octree argument");
- /* else initialize and run our calculation */
- init();
- if (gargc+1 < argc)
- for (i = gargc+1; i < argc; i++) {
- if ((fp = fopen(argv[i], "r")) == NULL) {
- sprintf(errmsg,
- "cannot open scene file \"%s\"", argv[i]);
- error(SYSTEM, errmsg);
- }
- filter(fp, argv[i]);
- fclose(fp);
- }
- else
- filter(stdin, "standard input");
- quit(0);
- }
-
-
- quit(status) /* exit with status */
- int status;
- {
- int rtstat;
-
- rtstat = close_process(rt.pd);
- if (status == 0)
- if (rtstat < 0)
- error(WARNING,
- "unknown return status from rtrace process");
- else
- status = rtstat;
- exit(status);
- }
-
-
- init() /* start rtrace and set up buffers */
- {
- extern int o_face(), o_sphere(), o_ring();
- int maxbytes;
- /* set up object functions */
- ofun[OBJ_FACE].funp = o_face;
- ofun[OBJ_SPHERE].funp = o_sphere;
- ofun[OBJ_RING].funp = o_ring;
- /* set up signal handling */
- signal(SIGPIPE, quit);
- /* start rtrace process */
- errno = 0;
- maxbytes = open_process(rt.pd, rtargv);
- if (maxbytes == 0) {
- eputs(rtargv[0]);
- eputs(": command not found\n");
- exit(1);
- }
- if (maxbytes < 0)
- error(SYSTEM, "cannot start rtrace process");
- rt.bsiz = maxbytes/(6*sizeof(float));
- rt.buf = (float *)malloc(6*sizeof(float)*rt.bsiz--);
- rt.dest = (float **)malloc(sizeof(float *)*rt.bsiz);
- if (rt.buf == NULL || rt.dest == NULL)
- error(SYSTEM, "out of memory in init");
- rt.nrays = 0;
- /* set up urand */
- initurand(2048);
- }
-
-
- eputs(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);
- midline = s[strlen(s)-1] != '\n';
- }
-
-
- wputs(s) /* print warning if enabled */
- char *s;
- {
- if (warnings)
- eputs(s);
- }
-
-
- filter(infp, name) /* process stream */
- register FILE *infp;
- char *name;
- {
- char buf[512];
- FILE *pfp;
- register int c;
-
- while ((c = getc(infp)) != EOF) {
- if (isspace(c))
- continue;
- if (c == '#') { /* comment/options */
- buf[0] = c;
- fgets(buf+1, sizeof(buf)-1, infp);
- xoptions(buf, name);
- } else if (c == '!') { /* command */
- buf[0] = c;
- fgetline(buf+1, sizeof(buf)-1, infp);
- if ((pfp = popen(buf+1, "r")) == NULL) {
- sprintf(errmsg, "cannot execute \"%s\"", buf);
- error(SYSTEM, errmsg);
- }
- filter(pfp, buf);
- pclose(pfp);
- } else { /* object */
- ungetc(c, infp);
- xobject(infp, name);
- }
- }
- }
-
-
- xoptions(s, nm) /* process options in string s */
- char *s;
- char *nm;
- {
- extern FILE *freopen();
- char buf[64];
- int nerrs = 0;
- register char *cp;
-
- if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
- fputs(s, stdout); /* not for us */
- return;
- }
- cp = s+10;
- while (*cp) {
- switch (*cp) {
- case ' ':
- case '\t':
- case '\n':
- cp++;
- continue;
- case 'm': /* material name */
- if (*++cp != '=')
- break;
- if (!*++cp)
- break;
- atos(thisillum.matname, MAXSTR, cp);
- cp = sskip(cp);
- if (!(thisillum.flags & IL_DATCLB)) {
- strcpy(thisillum.datafile, thisillum.matname);
- thisillum.dfnum = 0;
- }
- continue;
- case 'f': /* data file name */
- if (*++cp != '=')
- break;
- if (!*++cp) {
- strcpy(thisillum.datafile,thisillum.matname);
- thisillum.dfnum = 0;
- thisillum.flags &= ~IL_DATCLB;
- continue;
- }
- atos(thisillum.datafile, MAXSTR, cp);
- cp = sskip(cp);
- thisillum.dfnum = 0;
- thisillum.flags |= IL_DATCLB;
- continue;
- case 'i': /* include material */
- case 'e': /* exclude material */
- if (cp[1] != '=')
- break;
- matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
- cp += 2;
- atos(matcheck, MAXSTR, cp);
- cp = sskip(cp);
- continue;
- case 'a': /* use everything */
- cp = sskip(cp);
- matselect = S_ALL;
- continue;
- case 'n': /* use nothing (passive) */
- cp = sskip(cp);
- matselect = S_NONE;
- continue;
- case 'c': /* color calculation */
- if (*++cp != '=')
- break;
- switch (*++cp) {
- case 'a': /* average */
- thisillum.flags = (thisillum.flags|IL_COLAVG)
- & ~IL_COLDST;
- break;
- case 'd': /* distribution */
- thisillum.flags |= (IL_COLDST|IL_COLAVG);
- break;
- case 'n': /* none */
- thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
- break;
- default:
- goto opterr;
- }
- cp = sskip(cp);
- continue;
- case 'd': /* point sample density */
- if (*++cp != '=')
- break;
- if (!isintd(++cp, " \t\n"))
- break;
- thisillum.sampdens = atoi(cp);
- cp = sskip(cp);
- continue;
- case 's': /* point super-samples */
- if (*++cp != '=')
- break;
- if (!isintd(++cp, " \t\n"))
- break;
- thisillum.nsamps = atoi(cp);
- cp = sskip(cp);
- continue;
- case 'l': /* light sources */
- cp++;
- if (*cp == '+')
- thisillum.flags |= IL_LIGHT;
- else if (*cp == '-')
- thisillum.flags &= ~IL_LIGHT;
- else
- break;
- cp++;
- continue;
- case 'b': /* brightness */
- if (*++cp != '=')
- break;
- if (!isfltd(++cp, " \t\n"))
- break;
- thisillum.minbrt = atof(cp);
- if (thisillum.minbrt < 0.)
- thisillum.minbrt = 0.;
- cp = sskip(cp);
- continue;
- case 'o': /* output file */
- if (*++cp != '=')
- break;
- if (!*++cp)
- break;
- atos(buf, sizeof(buf), cp);
- cp = sskip(cp);
- if (freopen(buf, "w", stdout) == NULL) {
- sprintf(errmsg,
- "cannot open output file \"%s\"", buf);
- error(SYSTEM, errmsg);
- }
- doneheader = 0;
- continue;
- case '!': /* processed file! */
- sprintf(errmsg, "(%s): already processed!", nm);
- error(WARNING, errmsg);
- matselect = S_NONE;
- return;
- }
- opterr: /* skip faulty option */
- cp = sskip(cp);
- nerrs++;
- }
- /* print header? */
- checkhead();
- /* issue warnings? */
- if (nerrs) {
- sprintf(errmsg, "(%s): %d error(s) in option line:",
- nm, nerrs);
- error(WARNING, errmsg);
- wputs(s);
- printf("# %s: the following option line has %d error(s):\n",
- progname, nerrs);
- }
- /* print pure comment */
- printf("# %s", s+2);
- }
-
-
- printopts() /* print out option default values */
- {
- printf("m=%-15s\t\t# material name\n", thisillum.matname);
- printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
- if (thisillum.flags & IL_COLAVG)
- if (thisillum.flags & IL_COLDST)
- printf("c=d\t\t\t\t# color distribution\n");
- else
- printf("c=a\t\t\t\t# color average\n");
- else
- printf("c=n\t\t\t\t# color none\n");
- if (thisillum.flags & IL_LIGHT)
- printf("l+\t\t\t\t# light type on\n");
- else
- printf("l-\t\t\t\t# light type off\n");
- printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
- printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
- printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
- }
-
-
- printhead(ac, av) /* print out header */
- register int ac;
- register char **av;
- {
- putchar('#');
- while (ac-- > 0) {
- putchar(' ');
- fputs(*av++, stdout);
- }
- fputs("\n#@mkillum !\n", stdout);
- }
-
-
- xobject(fp, nm) /* translate an object from fp */
- FILE *fp;
- char *nm;
- {
- OBJREC thisobj;
- char str[MAXSTR];
- int doit;
- /* read the object */
- if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
- goto readerr;
- if (fgetword(str, MAXSTR, fp) == NULL)
- goto readerr;
- /* is it an alias? */
- if (!strcmp(str, ALIASID)) {
- if (fgetword(str, MAXSTR, fp) == NULL)
- goto readerr;
- printf("\n%s %s %s", thisillum.altmat, ALIASID, str);
- if (fgetword(str, MAXSTR, fp) == NULL)
- goto readerr;
- printf("\t%s\n", str);
- return;
- }
- thisobj.omod = OVOID; /* unused field */
- if ((thisobj.otype = otype(str)) < 0) {
- sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
- error(USER, errmsg);
- }
- if (fgetword(str, MAXSTR, fp) == NULL)
- goto readerr;
- thisobj.oname = str;
- if (readfargs(&thisobj.oargs, fp) != 1)
- goto readerr;
- thisobj.os = NULL;
- /* check for translation */
- switch (matselect) {
- case S_NONE:
- doit = 0;
- break;
- case S_ALL:
- doit = 1;
- break;
- case S_ELEM:
- doit = !strcmp(thisillum.altmat, matcheck);
- break;
- case S_COMPL:
- doit = strcmp(thisillum.altmat, matcheck);
- break;
- }
- doit = doit && issurface(thisobj.otype);
- /* print header? */
- checkhead();
- /* process object */
- if (doit)
- (*ofun[thisobj.otype].funp)(&thisobj, &thisillum, &rt, nm);
- else
- printobj(thisillum.altmat, &thisobj);
- /* free arguments */
- freefargs(&thisobj.oargs);
- return;
- readerr:
- sprintf(errmsg, "(%s): error reading scene", nm);
- error(USER, errmsg);
- }
-