static void appendview( /* append standard view */ char *nm, VIEW *vp ) { FILE *fp; /* check if already in there */ if (!memcmp(&thisview, vwl[currentview].v, sizeof(VIEW))) { error(COMMAND, "view already in standard list"); return; } /* append to file */ if ((fp = fopen(radfile, "a")) == NULL) { error(COMMAND, "cannot append rad input file"); return; } fputs("view=", fp); if (nm != NULL) { fputc(' ', fp); fputs(nm, fp); } fprintview(vp, fp); fputc('\n', fp); fclose(fp); /* append to our list */ while (vwl[currentview].v != NULL) currentview++; if (currentview >= MAXVIEW) error(INTERNAL, "too many views in appendview"); vwl[currentview].v = (VIEW *)bmalloc(sizeof(VIEW)); *(vwl[currentview].v) = thisview; if (nm != NULL) vwl[currentview].nam = savqstr(nm); }
/* Copy geometry string to file for wrapBSDF */ static char * save_geom(const char *mgf) { char *tfname = mktemp(savqstr(TEMPLATE)); int fd = open(tfname, O_CREAT|O_WRONLY, 0600); if (fd < 0) return(NULL); write(fd, mgf, strlen(mgf)); close(fd); add_wbsdf("-g", 1); add_wbsdf(tfname, 1); return(tfname); }
/* Add argument to wrapBSDF, allocating space if !isstatic */ static void add_wbsdf(const char *arg, int isstatic) { if (arg == NULL) return; if (wbsdfac >= MAXCARG-1) { fputs(progname, stderr); fputs(": too many command arguments to wrapBSDF\n", stderr); exit(1); } if (!*arg) arg = ""; else if (!isstatic) arg = savqstr((char *)arg); wrapBSDF[wbsdfac++] = (char *)arg; }
struct strvar * getsvar( /* get string variable */ char *svname ) { register struct strvar *sv; for (sv = svhead; sv != NULL; sv = sv->next) if (!strcmp(sv->name, svname)) return(sv); sv = (struct strvar *)emalloc(sizeof(struct strvar)); sv->name = savqstr(svname); sv->val = sv->preset = NULL; sv->next = svhead; svhead = sv; return(sv); }
/* Open XYZ component file for output and add appropriate arguments */ static FILE * open_component_file(int c) { static const char sname[3][6] = {"CIE-X", "CIE-Y", "CIE-Z"}; static const char cname[4][4] = {"-rf", "-tf", "-tb", "-rb"}; char *tfname = mktemp(savqstr(TEMPLATE)); FILE *fp = fopen(tfname, "w"); if (fp == NULL) { fprintf(stderr, "%s: cannot open '%s' for writing\n", progname, tfname); exit(1); } add_wbsdf("-s", 1); add_wbsdf(sname[c], 1); add_wbsdf(cname[(input_orient>0)<<1 | (output_orient>0)], 1); add_wbsdf(tfname, 1); return(fp); }
static void svpreset( /* preset a string variable */ char *eqn ) { register struct strvar *sv; register char *val; for (val = eqn; *val != '='; val++) if (!*val) return; *val++ = '\0'; sv = getsvar(eqn); if (sv->preset != NULL) freqstr(sv->preset); if (sv->val != NULL) freqstr(sv->val); sv->val = sv->preset = savqstr(val); *--val = '='; }
int /* create an extended triangle */ cvtri( OBJECT mo, FVECT vp1, FVECT vp2, FVECT vp3, FVECT vn1, FVECT vn2, FVECT vn3, RREAL vc1[2], RREAL vc2[2], RREAL vc3[2] ) { static OBJECT fobj = OVOID; char buf[32]; int flags; TRIDATA *ts; FACE *f; OBJREC *fop; int j; flags = MT_V; /* check what we have */ if (vn1 != NULL && vn2 != NULL && vn3 != NULL) { RREAL *rp; switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) { case ISBENT: flags |= MT_N; /* fall through */ case ISFLAT: break; case RVBENT: flags |= MT_N; rp = vn1; vn1 = vn3; vn3 = rp; /* fall through */ case RVFLAT: rp = vp1; vp1 = vp3; vp3 = rp; rp = vc1; vc1 = vc3; vc3 = rp; break; case DEGEN: error(WARNING, "degenerate triangle"); return(0); default: error(INTERNAL, "bad return from flat_tri()"); } } if (vc1 != NULL && vc2 != NULL && vc3 != NULL) flags |= MT_UV; if (fobj == OVOID) { /* create new triangle object */ fobj = newobject(); if (fobj == OVOID) goto nomem; fop = objptr(fobj); fop->omod = mo; fop->otype = OBJ_FACE; sprintf(buf, "t%ld", (long)fobj); fop->oname = savqstr(buf); fop->oargs.nfargs = 9; fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL)); if (fop->oargs.farg == NULL) goto nomem; } else { /* else reuse failed one */ fop = objptr(fobj); if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9) error(CONSISTENCY, "code error 1 in cvtri"); } for (j = 3; j--; ) { fop->oargs.farg[j] = vp1[j]; fop->oargs.farg[3+j] = vp2[j]; fop->oargs.farg[6+j] = vp3[j]; } /* create face record */ f = getface(fop); if (f->area == 0.) { free_os(fop); return(0); } if (fop->os != (char *)f) error(CONSISTENCY, "code error 2 in cvtri"); /* follow with auxliary data */ f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags)); if (f == NULL) goto nomem; fop->os = (char *)f; ts = (TRIDATA *)(f+1); ts->fl = flags; ts->obj = OVOID; if (flags & MT_N) for (j = 3; j--; ) { ts->vn[0][j] = vn1[j]; ts->vn[1][j] = vn2[j]; ts->vn[2][j] = vn3[j]; } if (flags & MT_UV) for (j = 2; j--; ) { ts->vc[0][j] = vc1[j]; ts->vc[1][j] = vc2[j]; ts->vc[2][j] = vc3[j]; } else vc1 = vc2 = vc3 = NULL; /* update bounds */ add2bounds(vp1, vc1); add2bounds(vp2, vc2); add2bounds(vp3, vc3); fobj = OVOID; /* we used this one */ return(1); nomem: error(SYSTEM, "out of memory in cvtri"); return(0); }
int main (int argc, char* argv []) { #define check(ol, al) if (argv [i][ol] || \ badarg(argc - i - 1,argv + i + 1, al)) \ goto badopt #define check_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; \ } int loadflags = IO_CHECK | IO_SCENE | IO_TREE | IO_BOUNDS, rval, i, j, n; char **portLp = photonPortList, **sensLp = photonSensorList, **amblp = NULL; struct stat pmstat; /* Global program name */ progname = fixargv0(argv [0]); /* Initialize object types */ initotypes(); /* Parse options */ for (i = 1; i < argc; i++) { /* Eggs-pand arguments */ while ((rval = expandarg(&argc, &argv, i))) if (rval < 0) { sprintf(errmsg, "cannot eggs-pand '%s'", argv [i]); error(SYSTEM, errmsg); } if (argv[i] == NULL) break; if (!strcmp(argv [i], "-version")) { puts(VersionID); quit(0); } if (!strcmp(argv [i], "-defaults") || !strcmp(argv [i], "-help")) { printdefaults(); quit(0); } /* Get octree */ if (i == argc - 1) { octname = argv [i]; break; } switch (argv [i][1]) { case 'a': /* Ambient */ switch (argv [i][2]) { case 'i': /* Ambient include */ case 'I': check(3, "s"); if (ambincl != 1) { ambincl = 1; amblp = amblist; } if (argv [i][2] == 'I') { /* Add modifiers from file */ rval = wordfile(amblp, AMBLLEN - (amblp - amblist), getpath(argv [++i], getrlibpath(), R_OK)); if (rval < 0) { sprintf(errmsg, "cannot open ambient include file \"%s\"", argv [i]); error(SYSTEM, errmsg); } amblp += rval; } else { /* Add modifier from next arg */ *amblp++ = savqstr(argv [++i]); *amblp = NULL; } break; case 'e': /* Ambient exclude */ case 'E': check(3, "s"); if (ambincl != 0) { ambincl = 0; amblp = amblist; } if (argv [i][2] == 'E') { /* Add modifiers from file */ rval = wordfile(amblp, AMBLLEN - (amblp - amblist), getpath(argv [++i], getrlibpath(), R_OK)); if (rval < 0) { sprintf(errmsg, "cannot open ambient exclude file \"%s\"", argv [i]); error(SYSTEM, errmsg); } amblp += rval; } else { /* Add modifier from next arg */ *amblp++ = savqstr(argv [++i]); *amblp = NULL; } break; case 'p': /* Pmap-specific */ switch (argv [i][3]) { case 'g': /* Global photon map */ check(4, "ss"); globalPmapParams.fileName = argv [++i]; globalPmapParams.distribTarget = parseMultiplier(argv [++i]); if (!globalPmapParams.distribTarget) goto badopt; globalPmapParams.minGather = globalPmapParams.maxGather = 0; break; case 'p': /* Precomputed global photon map */ check(4, "ssi"); preCompPmapParams.fileName = argv [++i]; preCompPmapParams.distribTarget = parseMultiplier(argv [++i]); if (!preCompPmapParams.distribTarget) goto badopt; preCompPmapParams.minGather = preCompPmapParams.maxGather = atoi(argv [++i]); if (!preCompPmapParams.maxGather) goto badopt; break; case 'c': /* Caustic photon map */ check(4, "ss"); causticPmapParams.fileName = argv [++i]; causticPmapParams.distribTarget = parseMultiplier(argv [++i]); if (!causticPmapParams.distribTarget) goto badopt; break; case 'v': /* Volume photon map */ check(4, "ss"); volumePmapParams.fileName = argv [++i]; volumePmapParams.distribTarget = parseMultiplier(argv [++i]); if (!volumePmapParams.distribTarget) goto badopt; break; case 'd': /* Direct photon map */ check(4, "ss"); directPmapParams.fileName = argv [++i]; directPmapParams.distribTarget = parseMultiplier(argv [++i]); if (!directPmapParams.distribTarget) goto badopt; break; case 'C': /* Contribution photon map */ check(4, "ss"); contribPmapParams.fileName = argv [++i]; contribPmapParams.distribTarget = parseMultiplier(argv [++i]); if (!contribPmapParams.distribTarget) goto badopt; break; case 'D': /* Predistribution factor */ check(4, "f"); preDistrib = atof(argv [++i]); if (preDistrib <= 0) error(USER, "predistrib factor must be > 0"); break; case 'M': /* Max predistribution passes */ check(4, "i"); maxPreDistrib = atoi(argv [++i]); if (maxPreDistrib <= 0) error(USER, "max predistrib passes must be > 0"); break; #if 1 /* Kept for backwards compat, to be phased out by -lr */ case 'm': /* Max photon bounces */ check(4, "i"); photonMaxBounce = atol(argv [++i]); if (photonMaxBounce <= 0) error(USER, "max photon bounces must be > 0"); break; #endif #ifdef PMAP_EKSPERTZ case 'i': /* Add region of interest */ check(4, "ffffff"); n = pmapNumROI; pmapROI = realloc(pmapROI, ++pmapNumROI * sizeof(PhotonMapROI)); if (!pmapROI) error(SYSTEM, "failed to allocate ROI"); pmapROI [n].min [0] = atof(argv [++i]); pmapROI [n].min [1] = atof(argv [++i]); pmapROI [n].min [2] = atof(argv [++i]); pmapROI [n].max [0] = atof(argv [++i]); pmapROI [n].max [1] = atof(argv [++i]); pmapROI [n].max [2] = atof(argv [++i]); for (j = 0; j < 3; j++) if (pmapROI [n].min [j] >= pmapROI [n].max [j]) error(USER, "invalid region of interest " "(swapped min/max?)"); break; #endif case 'P': /* Global photon precomp ratio */ check(4, "f"); finalGather = atof(argv [++i]); if (finalGather <= 0 || finalGather > 1) error(USER, "global photon precomputation ratio " "must be in range ]0, 1]"); break; case 'o': /* Photon port */ case 'O': check(4, "s"); if (argv [i][3] == 'O') { /* Add port modifiers from file */ rval = wordfile(portLp, MAXSET - (portLp - photonPortList), getpath(argv [++i], getrlibpath(), R_OK)); if (rval < 0) { sprintf(errmsg, "cannot open photon port file %s", argv [i]); error(SYSTEM, errmsg); } portLp += rval; } else { /* Add port modifier from next arg, mark end with * NULL */ *portLp++ = savqstr(argv [++i]); *portLp = NULL; } break; case 'r': /* Random seed */ check(4, "i"); randSeed = atoi(argv [++i]); break; case 's': /* Antimatter sensor */ case 'S': check(4, "s"); if (argv[i][3] == 'S') { /* Add sensor modifiers from file */ rval = wordfile(sensLp, MAXSET - (sensLp - photonSensorList), getpath(argv [++i], getrlibpath(), R_OK)); if (rval < 0) { sprintf(errmsg, "cannot open antimatter sensor file %s", argv [i]); error(SYSTEM, errmsg); } sensLp += rval; } else { /* Append modifier to sensor list, mark end with * NULL */ *sensLp++ = savqstr(argv [++i]); *sensLp = NULL; } break; default: goto badopt; } break; default: goto badopt; } break; case 'b': /* Back face visibility */ if (argv [i][2] == 'v') { check_bool(3, backvis); } else goto badopt; break; case 'd': /* Direct */ switch (argv [i][2]) { case 'p': /* PDF samples */ check(3, "f"); pdfSamples = atof(argv [++i]); break; case 's': /* Source partition size ratio */ check(3, "f"); srcsizerat = atof(argv [++i]); break; default: goto badopt; } break; case 'e': /* Diagnostics file */ check(2, "s"); diagFile = argv [++i]; break; case 'f': /* Force overwrite */ if (argv [i][2] == 'o') { check_bool(3, clobber); } else goto badopt; break; #ifdef PMAP_EKSPERTZ case 'l': /* Limits */ switch (argv [i][2]) { case 'd': /* Limit photon path distance */ check(3, "f"); photonMaxDist = atof(argv [++i]); if (photonMaxDist <= 0) error(USER, "max photon distance must be > 0"); break; case 'r': /* Limit photon bounces */ check(3, "i"); photonMaxBounce = atol(argv [++i]); if (photonMaxBounce <= 0) error(USER, "max photon bounces must be > 0"); break; default: goto badopt; } break; #endif case 'm': /* Medium */ switch (argv[i][2]) { case 'e': /* Eggs-tinction coefficient */ check(3, "fff"); setcolor(cextinction, atof(argv [i + 1]), atof(argv [i + 2]), atof(argv [i + 3])); i += 3; break; case 'a': /* Albedo */ check(3, "fff"); setcolor(salbedo, atof(argv [i + 1]), atof(argv [i + 2]), atof(argv [i + 3])); i += 3; break; case 'g': /* Scattering eccentricity */ check(3, "f"); seccg = atof(argv [++i]); break; default: goto badopt; } break; #if NIX case 'n': /* Num parallel processes (NIX only) */ check(2, "i"); nproc = atoi(argv [++i]); if (nproc > PMAP_MAXPROC) { nproc = PMAP_MAXPROC; sprintf(errmsg, "too many parallel processes, clamping to " "%d\n", nproc); error(WARNING, errmsg); } break; #endif case 't': /* Timer */ check(2, "i"); photonRepTime = atoi(argv [++i]); break; case 'v': /* Verbosity */ check_bool(2, verbose); break; #ifdef EVALDRC_HACK case 'A': /* Angular source file */ check(2,"s"); angsrcfile = argv[++i]; break; #endif default: goto badopt; } } /* Open diagnostics file */ if (diagFile) { if (!freopen(diagFile, "a", stderr)) quit(2); fprintf(stderr, "**************\n*** PID %5d: ", getpid()); printargs(argc, argv, stderr); putc('\n', stderr); fflush(stderr); } #ifdef NICE /* Lower priority */ nice(NICE); #endif if (octname == NULL) error(USER, "missing octree argument"); /* Allocate photon maps and set parameters */ for (i = 0; i < NUM_PMAP_TYPES; i++) { setPmapParam(photonMaps + i, pmapParams + i); /* Don't overwrite existing photon map unless clobbering enabled */ if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) && !clobber) { sprintf(errmsg, "photon map file %s exists, not overwritten", photonMaps [i] -> fileName); error(USER, errmsg); } } for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++); if (i >= NUM_PMAP_TYPES) error(USER, "no photon maps specified"); readoct(octname, loadflags, &thescene, NULL); #ifdef EVALDRC_HACK if (angsrcfile) readobj(angsrcfile); /* load angular sources */ #endif nsceneobjs = nobjects; /* Get sources */ marksources(); /* Do forward pass and build photon maps */ if (contribPmap) /* Just build contrib pmap, ignore others */ distribPhotonContrib(contribPmap, nproc); else distribPhotons(photonMaps, nproc); /* Save photon maps; no idea why GCC needs an explicit cast here... */ savePmaps((const PhotonMap**)photonMaps, argc, argv); cleanUpPmaps(photonMaps); quit(0); badopt: sprintf(errmsg, "command line error at '%s'", argv[i]); error(USER, errmsg); #undef check #undef check_bool return 0; }
static void runrad( /* run rad and load variables */ int ac, char **av ) { static char optfile[] = TEMPLATE; int nvn = 0, nvv = 0; FILE *fp; register char *cp; char radcomm[256], buf[128], nam[32]; /* set rad commmand */ strcpy(radcomm, "rad -w -v 0 "); /* look out below! */ cp = radcomm + 19; if (silent) { strcpy(cp, "-s "); cp += 3; } while (ac--) { strcpy(cp, *av++); while (*cp) cp++; *cp++ = ' '; } strcpy(cp, "OPTFILE="); /* create temporary options file */ strcpy(cp+8, mktemp(optfile)); if (system(radcomm)) /* update octree */ error(USER, "error executing rad command"); /* replace "-v 0" with "-n -e -s -V" */ strcpy(radcomm+7, "-n -e -s -V"); radcomm[18] = ' '; if ((fp = popen(radcomm, "r")) == NULL) error(SYSTEM, "cannot start rad command"); buf[0] = '\0'; /* read variables alphabetically */ /* get exposure */ if ((cp = scan4var(buf, sizeof(buf), "EXPOSURE", fp)) != NULL) { expval = atof(cp); if ((*cp == '-') | (*cp == '+')) expval = pow(2., expval); expval *= 0.5; /* compensate for local shading */ } /* look for eye separation */ if ((cp = scan4var(buf, sizeof(buf), "EYESEP", fp)) != NULL) eyedist = atof(cp); /* look for materials */ while ((cp = scan4var(buf, sizeof(buf), "materials", fp)) != NULL) { nscenef += wordstring(scene+nscenef, cp); buf[0] = '\0'; } /* look for octree */ if ((cp = scan4var(buf, sizeof(buf), "OCTREE", fp)) != NULL) octree = savqstr(cp); /* look for scene files */ while ((cp = scan4var(buf, sizeof(buf), "scene", fp)) != NULL) { nscenef += wordstring(scene+nscenef, cp); buf[0] = '\0'; } /* load view names */ while ((cp = scan4var(buf, sizeof(buf), "view", fp)) != NULL) { if (nvn >= MAXVIEW) error(INTERNAL, "too many views in rad file"); vwl[nvn++].nam = *cp == '-' ? (char *)NULL : savqstr(atos(nam, sizeof(nam), cp)); buf[0] = '\0'; } /* load actual views */ do if (isview(buf)) { vwl[nvv].v = (VIEW *)bmalloc(sizeof(VIEW)); *(vwl[nvv].v) = stdview; sscanview(vwl[nvv].v, buf); if ((cp = setview(vwl[nvv++].v)) != NULL) { fprintf(stderr, "%s: bad view %d - %s\n", progname, nvv, cp); quit(1); } } while (fgets(buf, sizeof(buf), fp) != NULL); if (nvv != nvn) error(INTERNAL, "view miscount in runrad"); pclose(fp); /* open options file */ if ((fp = fopen(optfile, "r")) == NULL) error(SYSTEM, "cannot open options file"); /* get relevant options */ while (fgets(buf, sizeof(buf), fp) != NULL) if (!strncmp(buf, "-av ", 4)) setcolor(ambval, atof(buf+4), atof(sskip2(buf+4,1)), atof(sskip2(buf+4,2))); else if (backvis && !strncmp(buf, "-bv", 3) && (!buf[3] || strchr("0-FfNn \n",buf[3])!=NULL)) backvis = 0; fclose(fp); unlink(optfile); /* delete options file */ }
static int getfield( /* get next field */ register struct field *f ) { static char buf[RMAXWORD+1]; /* no recursion! */ int delim, inword; double d; char *np; register char *cp; switch (f->type & F_TYP) { case T_LIT: cp = f->f.sl; do { if (blnkeq && isblnk(*cp)) { if (!isblnk(ipb.chr)) return(-1); do cp++; while (isblnk(*cp)); do scaninp(); while (isblnk(ipb.chr)); } else if (*cp == ipb.chr) { cp++; scaninp(); } else return(-1); } while (*cp); return(0); case T_STR: if (f->next == NULL || (f->next->type & F_TYP) != T_LIT) delim = EOF; else delim = f->next->f.sl[0]; cp = buf; do { if (ipb.chr == EOF || ipb.chr == '\n') inword = 0; else if (blnkeq && delim != EOF) inword = isblnk(delim) ? !isblnk(ipb.chr) : ipb.chr != delim; else inword = cp-buf < (f->type & F_WID); if (inword) { *cp++ = ipb.chr; scaninp(); } } while (inword && cp < &buf[RMAXWORD]); *cp = '\0'; if (f->f.sv->val == NULL) f->f.sv->val = savqstr(buf); /* first setting */ else if (strcmp(f->f.sv->val, buf)) return(-1); /* doesn't match! */ return(0); case T_NUM: if (f->next == NULL || (f->next->type & F_TYP) != T_LIT) delim = EOF; else delim = f->next->f.sl[0]; np = NULL; cp = buf; do { if (!((np==NULL&&isblnk(ipb.chr)) || isnum(ipb.chr))) inword = 0; else if (blnkeq && delim != EOF) inword = isblnk(delim) ? !isblnk(ipb.chr) : ipb.chr != delim; else inword = cp-buf < (f->type & F_WID); if (inword) { if (np==NULL && !isblnk(ipb.chr)) np = cp; *cp++ = ipb.chr; scaninp(); } } while (inword && cp < &buf[RMAXWORD]); *cp = '\0'; d = np==NULL ? 0. : atof(np); if (!vardefined(f->f.nv)) varset(f->f.nv, '=', d); /* first setting */ else if ((d = (varvalue(f->f.nv)-d)/(d==0.?1.:d)) > .001 || d < -.001) return(-1); /* doesn't match! */ return(0); } return -1; /* pro forma return */ }
static void readfmt( /* read record format */ char *spec, int output ) { int fd; char *inptr; struct field fmt; int res; register struct field *f; /* check for inline format */ for (inptr = spec; *inptr; inptr++) if (*inptr == '$') break; if (*inptr) /* inline */ inptr = spec; else { /* from file */ if ((fd = open(spec, 0)) == -1) { eputs(spec); eputs(": cannot open\n"); quit(1); } res = read(fd, inpbuf+2, INBSIZ-2); if (res <= 0 || res >= INBSIZ-1) { eputs(spec); if (res < 0) eputs(": read error\n"); else if (res == 0) eputs(": empty file\n"); else if (res >= INBSIZ-1) eputs(": format too long\n"); quit(1); } close(fd); (inptr=inpbuf+2)[res] = '\0'; } f = &fmt; /* get fields */ while ((res = readfield(&inptr)) != F_NUL) { f->next = (struct field *)emalloc(sizeof(struct field)); f = f->next; f->type = res; switch (res & F_TYP) { case T_LIT: f->f.sl = savqstr(inpbuf); break; case T_STR: f->f.sv = getsvar(inpbuf); break; case T_NUM: if (output) f->f.ne = eparse(inpbuf); else f->f.nv = savestr(inpbuf); break; } /* add final newline if necessary */ if (!igneol && *inptr == '\0' && inptr[-1] != '\n') inptr = "\n"; } f->next = NULL; if (output) outfmt = fmt.next; else inpfmt = fmt.next; }
int getPmapRenderOpt (int ac, char *av []) /* Parse next render option for photon map; interface to getrenderopt(); * return -1 if parsing failed, else number of parameters consumed */ { #define check(ol,al) (av[0][ol] || badarg(ac-1,av+1,al)) static int t = -1; /* pmap parameter index */ if (ac < 1 || !av [0] || av [0][0] != '-') return -1; switch (av [0][1]) { case 'a': switch (av [0][2]) { case 'p': /* photon map */ /* Asking for photon map, ergo ambounce != 0 */ ambounce += (ambounce == 0); if (!check(3, "s")) { /* File -> assume bwidth = 1 or precomputed pmap */ if (++t >= NUM_PMAP_TYPES) error(USER, "too many photon maps"); pmapParams [t].fileName = savqstr(av [1]); pmapParams [t].minGather = pmapParams [t].maxGather = defaultGather; } else return -1; if (!check(3, "si")) { /* File + bandwidth */ pmapParams [t].minGather = pmapParams [t].maxGather = atoi(av [2]); if (!pmapParams [t].minGather) return -1; } else { sprintf(errmsg, "no photon lookup bandwidth specified, " "using default %d", defaultGather); error(WARNING, errmsg); return 1; } if (!check(3, "sii")) { /* File + min bwidth + max bwidth -> bias compensation */ pmapParams [t].maxGather = atoi(av [3]); if (pmapParams [t].minGather >= pmapParams [t].maxGather) return -1; return 3; } else return 2; case 'm': /* Fixed max photon search radius */ if (check(3, "f") || (maxDistFix = atof(av [1])) <= 0) error(USER, "invalid max photon search radius coefficient"); return 1; #ifdef PMAP_OOC case 'c': /* OOC pmap cache page size ratio */ if (check(3, "f") || (pmapCachePageSize = atof(av [1])) <= 0) error(USER, "invalid photon cache page size ratio"); return 1; case 'C': /* OOC pmap cache size (in photons); 0 = no caching */ if (check(3, "s")) error(USER, "invalid number of cached photons"); /* Parsing failure sets to zero and disables caching */ pmapCacheSize = parseMultiplier(av [1]); return 1; #endif } } #undef check /* Unknown option */ return -1; }
int readoct( /* read in octree file or stream */ char *inpspec, int load, CUBE *scene, char *ofn[] ) { char sbuf[512]; int nf; int i; long m; if (inpspec == NULL) { infn = "standard input"; infp = stdin; } else if (inpspec[0] == '!') { infn = inpspec; if ((infp = popen(inpspec+1, "r")) == NULL) { sprintf(errmsg, "cannot execute \"%s\"", inpspec); error(SYSTEM, errmsg); } } else { infn = inpspec; if ((infp = fopen(inpspec, "r")) == NULL) { sprintf(errmsg, "cannot open octree file \"%s\"", inpspec); error(SYSTEM, errmsg); } } SET_FILE_BINARY(infp); /* get header */ if (checkheader(infp, OCTFMT, load&IO_INFO ? stdout : (FILE *)NULL) < 0) octerror(USER, "not an octree"); /* check format */ if ((objsize = ogetint(2)-OCTMAGIC) <= 0 || objsize > MAXOBJSIZ || objsize > sizeof(long)) octerror(USER, "incompatible octree format"); /* get boundaries */ if (load & IO_BOUNDS) { for (i = 0; i < 3; i++) scene->cuorg[i] = atof(ogetstr(sbuf)); scene->cusize = atof(ogetstr(sbuf)); } else { for (i = 0; i < 4; i++) ogetstr(sbuf); } objorig = nobjects; /* set object offset */ nf = 0; /* get object files */ while (*ogetstr(sbuf)) { if (load & IO_SCENE) readobj(sbuf); if (load & IO_FILES) ofn[nf] = savqstr(sbuf); nf++; } if (load & IO_FILES) ofn[nf] = NULL; /* get number of objects */ fnobjects = m = ogetint(objsize); if (fnobjects != m) octerror(USER, "too many objects"); if (load & IO_TREE) /* get the octree */ scene->cutree = gettree(); else if (load & IO_SCENE && nf == 0) skiptree(); if (load & IO_SCENE) { /* get the scene */ if (nf == 0) { /* load binary scene data */ readscene(infp, objsize); } else { /* consistency checks */ /* check object count */ if (nobjects != objorig+fnobjects) octerror(USER, "bad object count; octree stale?"); /* check for non-surfaces */ if (nonsurfintree(scene->cutree)) octerror(USER, "modifier in tree; octree stale?"); } } /* close the input */ if (infn[0] == '!') pclose(infp); else fclose(infp); return(nf); }
void getobject( /* read the next object */ char *name, FILE *fp ) { #define OALIAS -2 OBJECT obj; char sbuf[MAXSTR]; int rval; OBJREC *objp; if ((obj = newobject()) == OVOID) error(SYSTEM, "out of object space"); objp = objptr(obj); /* get modifier */ strcpy(sbuf, "EOF"); fgetword(sbuf, MAXSTR, fp); if (strchr(sbuf, '\t')) { sprintf(errmsg, "(%s): illegal tab in modifier \"%s\"", name, sbuf); error(USER, errmsg); } if (!strcmp(sbuf, VOIDID)) objp->omod = OVOID; else if (!strcmp(sbuf, ALIASMOD)) objp->omod = OALIAS; else if ((objp->omod = modifier(sbuf)) == OVOID) { sprintf(errmsg, "(%s): undefined modifier \"%s\"", name, sbuf); error(USER, errmsg); } /* get type */ strcpy(sbuf, "EOF"); fgetword(sbuf, MAXSTR, fp); if ((objp->otype = otype(sbuf)) < 0) { sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf); error(USER, errmsg); } /* get identifier */ sbuf[0] = '\0'; fgetword(sbuf, MAXSTR, fp); if (strchr(sbuf, '\t')) { sprintf(errmsg, "(%s): illegal tab in identifier \"%s\"", name, sbuf); error(USER, errmsg); } objp->oname = savqstr(sbuf); /* get arguments */ if (objp->otype == MOD_ALIAS) { OBJECT alias; strcpy(sbuf, "EOF"); fgetword(sbuf, MAXSTR, fp); if ((alias = modifier(sbuf)) == OVOID) { sprintf(errmsg, "(%s): bad reference \"%s\"", name, sbuf); objerror(objp, USER, errmsg); } if (objp->omod == OALIAS || objp->omod == objptr(alias)->omod) { objp->omod = alias; } else { objp->oargs.sarg = (char **)malloc(sizeof(char *)); if (objp->oargs.sarg == NULL) error(SYSTEM, "out of memory in getobject"); objp->oargs.nsargs = 1; objp->oargs.sarg[0] = savestr(sbuf); } } else if ((rval = readfargs(&objp->oargs, fp)) == 0) { sprintf(errmsg, "(%s): bad arguments", name); objerror(objp, USER, errmsg); } else if (rval < 0) { sprintf(errmsg, "(%s): error reading scene", name); error(SYSTEM, errmsg); } if (objp->omod == OALIAS) { sprintf(errmsg, "(%s): inappropriate use of '%s' modifier", name, ALIASMOD); objerror(objp, USER, errmsg); } /* initialize */ objp->os = NULL; insertobject(obj); /* add to global structure */ #undef OALIAS }