--- ray/src/util/rfluxmtx.c 2014/07/19 01:19:49 2.1 +++ ray/src/util/rfluxmtx.c 2014/07/22 23:21:56 2.5 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rfluxmtx.c,v 2.1 2014/07/19 01:19:49 greg Exp $"; +static const char RCSid[] = "$Id: rfluxmtx.c,v 2.5 2014/07/22 23:21:56 greg Exp $"; #endif /* * Calculate flux transfer matrix or matrices using rcontrib @@ -23,10 +23,10 @@ static const char RCSid[] = "$Id: rfluxmtx.c,v 2.1 201 #endif #ifdef _WIN32 -#define SPECIALS " \t$*?" +#define SPECIALS " \t\"$*?" #define QUOTCHAR '"' #else -#define SPECIALS " \t\n'\"()${}*?[]" +#define SPECIALS " \t\n'\"()${}*?[];|&" #define QUOTCHAR '\'' #define ALTQUOT '"' #endif @@ -45,15 +45,16 @@ const char overflowerr[] = "%s: too many arguments!\n" #define CHECKARGC(n) if (nrcargs >= MAXRCARG-(n)) \ { fprintf(stderr, overflowerr, progname); exit(1); } -int sampcnt = 0; /* sample count (unset) */ +int sampcnt = 0; /* sample count (0==unset) */ -char *reinhfn = "reinhart.cal"; -char *shirchufn = "disk2square.cal"; +char *reinhfn = "reinhartb.cal"; +char *shirchiufn = "disk2square.cal"; char *kfullfn = "klems_full.cal"; char *khalffn = "klems_half.cal"; char *kquarterfn = "klems_quarter.cal"; -#define PARAMSTART "@rfluxmtx" /* string indicating parameters */ + /* string indicating parameters */ +const char PARAMSTART[] = "@rfluxmtx"; /* surface type IDs */ #define ST_NONE 0 @@ -66,10 +67,10 @@ typedef struct surf_s { void *priv; /* private data (malloc'ed) */ char sname[32]; /* surface name */ FVECT snrm; /* surface normal */ - double area; /* surface area (or solid angle) */ + double area; /* surface area / proj. solid angle */ short styp; /* surface type */ - short nfargs; /* number of arguments */ - double farg[1]; /* arguments (extends struct) */ + short nfargs; /* number of real arguments */ + double farg[1]; /* real values (extends struct) */ } SURF; /* surface structure */ typedef struct { @@ -372,7 +373,13 @@ parse_params(char *pargs) static void finish_receiver(void) { - char binbuf[128]; + char sbuf[256]; + int uniform = 0; + char *calfn = NULL; + char *params = NULL; + char *binv = NULL; + char *binf = NULL; + char *nbins = NULL; if (!curmod[0]) { fputs(progname, stderr); @@ -384,7 +391,7 @@ finish_receiver(void) rcarg[nrcargs++] = "-o"; rcarg[nrcargs++] = curparams.outfn; } - /* add bin specification */ + /* check arguments */ if (!curparams.hemis[0]) { fputs(progname, stderr); fputs(": missing hemisphere sampling type!\n", stderr); @@ -400,91 +407,97 @@ finish_receiver(void) curparams.vup[2] = 1; else curparams.vup[1] = 1; + /* determine sample type/bin */ if (tolower(curparams.hemis[0]) == 'u' | curparams.hemis[0] == '1') { - CHECKARGC(2); - rcarg[nrcargs++] = "-b"; - rcarg[nrcargs++] = "0"; + binv = "0"; /* uniform sampling -- one bin */ + uniform = 1; } else if (tolower(curparams.hemis[0]) == 's' && tolower(curparams.hemis[1]) == 'c') { - if (shirchufn != NULL) { - CHECKARGC(2); - rcarg[nrcargs++] = "-f"; - rcarg[nrcargs++] = shirchufn; - shirchufn = NULL; - } -fputs("Shirley-Chiu unimplemented...\n",stderr); exit(1); + /* assign parameters */ if (curparams.hsiz <= 1) { fputs(progname, stderr); fputs(": missing size for Shirley-Chiu sampling!\n", stderr); exit(1); } + calfn = shirchiufn; shirchiufn = NULL; + sprintf(sbuf, "SCdim=%d,Nx=%g,Ny=%g,Nz=%g,Ux=%g,Uy=%g,Uz=%g", + curparams.hsiz, + curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], + curparams.vup[0], curparams.vup[1], curparams.vup[2]); + params = savqstr(sbuf); + binv = "scbin"; + nbins = "SCdim*SCdim"; } else if ((tolower(curparams.hemis[0]) == 'r') | (tolower(curparams.hemis[0]) == 't')) { - if (reinhfn != NULL) { - CHECKARGC(2); - rcarg[nrcargs++] = "-f"; - rcarg[nrcargs++] = reinhfn; - reinhfn = NULL; - } -fputs("Reinhart/Tregenza unimplemented...\n",stderr); exit(1); + calfn = reinhfn; reinhfn = NULL; + sprintf(sbuf, "MF=%d,Nx=%g,Ny=%g,Nz=%g,Ux=%g,Uy=%g,Uz=%g", + curparams.hsiz, + curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], + curparams.vup[0], curparams.vup[1], curparams.vup[2]); + params = savqstr(sbuf); + binv = "rbin"; + nbins = "Nrbins"; } else if (tolower(curparams.hemis[0]) == 'k' && !curparams.hemis[1] | (tolower(curparams.hemis[1]) == 'f') | (curparams.hemis[1] == '1')) { - if (kfullfn != NULL) { - CHECKARGC(2); - rcarg[nrcargs++] = "-f"; - rcarg[nrcargs++] = kfullfn; - kfullfn = NULL; - } - CHECKARGC(4); - sprintf(binbuf, "kbin(%g,%g,%g,%g,%g,%g)", - curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], - curparams.vup[0], curparams.vup[1], curparams.vup[2]); - rcarg[nrcargs++] = "-b"; - rcarg[nrcargs++] = savqstr(binbuf); - rcarg[nrcargs++] = "-bn"; - rcarg[nrcargs++] = "Nkbins"; + calfn = kfullfn; kfullfn = NULL; + binf = "kbin"; + nbins = "Nkbins"; } else if (tolower(curparams.hemis[0]) == 'k' && (tolower(curparams.hemis[1]) == 'h') | (curparams.hemis[1] == '2')) { - if (khalffn != NULL) { - CHECKARGC(2); - rcarg[nrcargs++] = "-f"; - rcarg[nrcargs++] = khalffn; - khalffn = NULL; - } - CHECKARGC(4); - sprintf(binbuf, "khbin(%g,%g,%g,%g,%g,%g)", - curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], - curparams.vup[0], curparams.vup[1], curparams.vup[2]); - rcarg[nrcargs++] = "-b"; - rcarg[nrcargs++] = savqstr(binbuf); - rcarg[nrcargs++] = "-bn"; - rcarg[nrcargs++] = "Nkhbins"; + calfn = khalffn; khalffn = NULL; + binf = "khbin"; + nbins = "Nkhbins"; } else if (tolower(curparams.hemis[0]) == 'k' && (tolower(curparams.hemis[1]) == 'q') | (curparams.hemis[1] == '4')) { - if (kquarterfn != NULL) { - CHECKARGC(2); - rcarg[nrcargs++] = "-f"; - rcarg[nrcargs++] = kquarterfn; - kquarterfn = NULL; - } - CHECKARGC(4); - sprintf(binbuf, "kqbin(%g,%g,%g,%g,%g,%g)", - curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], - curparams.vup[0], curparams.vup[1], curparams.vup[2]); - rcarg[nrcargs++] = "-b"; - rcarg[nrcargs++] = savqstr(binbuf); - rcarg[nrcargs++] = "-bn"; - rcarg[nrcargs++] = "Nkqbins"; + calfn = kquarterfn; kquarterfn = NULL; + binf = "kqbin"; + nbins = "Nkqbins"; } else { fprintf(stderr, "%s: unrecognized hemisphere sampling: h=%s\n", progname, curparams.hemis); exit(1); } - CHECKARGC(2); /* modifier argument goes last */ + if (!uniform & (curparams.slist->styp == ST_SOURCE)) { + SURF *sp; + for (sp = curparams.slist; sp != NULL; sp = sp->next) + if (fabs(sp->area - PI) > 1e-3) { + fprintf(stderr, "%s: source '%s' must be 180-degrees\n", + progname, sp->sname); + exit(1); + } + } + if (calfn != NULL) { /* add cal file if needed */ + CHECKARGC(2); + rcarg[nrcargs++] = "-f"; + rcarg[nrcargs++] = calfn; + } + if (params != NULL) { /* parameters _after_ cal file */ + CHECKARGC(2); + rcarg[nrcargs++] = "-p"; + rcarg[nrcargs++] = params; + } + if (nbins != NULL) { /* add #bins if set */ + CHECKARGC(2); + rcarg[nrcargs++] = "-bn"; + rcarg[nrcargs++] = nbins; + } + if (binv != NULL) { + CHECKARGC(2); /* assign bin variable */ + rcarg[nrcargs++] = "-b"; + rcarg[nrcargs++] = binv; + } else if (binf != NULL) { + CHECKARGC(2); /* assign bin function */ + rcarg[nrcargs++] = "-b"; + sprintf(sbuf, "%s(%g,%g,%g,%g,%g,%g)", binf, + curparams.nrm[0], curparams.nrm[1], curparams.nrm[2], + curparams.vup[0], curparams.vup[1], curparams.vup[2]); + rcarg[nrcargs++] = savqstr(sbuf); + } + CHECKARGC(2); /* modifier argument goes last */ rcarg[nrcargs++] = "-m"; rcarg[nrcargs++] = savqstr(curmod); } @@ -979,7 +992,8 @@ add_surface(int st, const char *oname, FILE *fp) VCOPY(snew->snrm, snew->farg); if (normalize(snew->snrm) == 0) goto badnorm; - snew->area = 2.*PI*(1. - cos((PI/180./2.)*snew->farg[3])); + snew->area = sin((PI/180./2.)*snew->farg[3]); + snew->area *= PI*snew->area; break; } if (snew->area <= FTINY) { @@ -1109,7 +1123,9 @@ load_scene(const char *inspec, int (*ocb)(FILE *)) continue; } if (c == '#') { /* parameters/comment */ - if (fscanf(fp, "%s", inpbuf) == 1 && + if ((c = getc(fp)) == EOF || ungetc(c,fp) == EOF) + break; + if (!isspace(c) && fscanf(fp, "%s", inpbuf) == 1 && !strcmp(inpbuf, PARAMSTART)) { if (fgets(inpbuf, sizeof(inpbuf), fp) != NULL) parse_params(inpbuf); @@ -1139,6 +1155,7 @@ int main(int argc, char *argv[]) { char fmtopt[6] = "-faa"; /* default output is ASCII */ + char *xrs=NULL, *yrs=NULL, *ldopt=NULL; char *sendfn; char sampcntbuf[32], nsbinbuf[32]; FILE *rcfp; @@ -1172,6 +1189,14 @@ main(int argc, char *argv[]) goto userr; } break; + case 'x': /* x-resolution */ + xrs = argv[++a]; + na = 0; + continue; + case 'y': /* y-resolution */ + yrs = argv[++a]; + na = 0; + continue; case 'c': /* number of samples */ sampcnt = atoi(argv[a+1]); if (sampcnt <= 0) @@ -1183,6 +1208,7 @@ main(int argc, char *argv[]) case 'u': case 'i': case 'h': + case 'r': break; case 'n': /* options with 1 argument */ case 's': @@ -1193,7 +1219,11 @@ main(int argc, char *argv[]) if (argv[a][2] != 'v') goto userr; break; case 'l': /* special case */ - if (argv[a][2] == 'd') goto userr; + if (argv[a][2] == 'd') { + ldopt = argv[a]; + na = 0; + continue; + } na = 2; break; case 'd': /* special case */ @@ -1224,6 +1254,20 @@ done_opts: if (sendfn[0] == '-') { /* user wants pass-through mode? */ if (sendfn[1]) goto userr; sendfn = NULL; + if (xrs) { + CHECKARGC(2); + rcarg[nrcargs++] = "-x"; + rcarg[nrcargs++] = xrs; + } + if (yrs) { + CHECKARGC(2); + rcarg[nrcargs++] = "-y"; + rcarg[nrcargs++] = yrs; + } + if (ldopt) { + CHECKARGC(1); + rcarg[nrcargs++] = ldopt; + } if (sampcnt <= 0) sampcnt = 1; } else { /* else FVECT determines input format */ fmtopt[3] = (sizeof(RREAL)==sizeof(double)) ? 'd' : 'f'; @@ -1276,7 +1320,7 @@ done_opts: userr: if (a < argc-2) fprintf(stderr, "%s: unsupported option '%s'", progname, argv[a]); - fprintf(stderr, "Usage: %s [rcontrib options] sender.rad receiver.rad [system.rad ..]\n", + fprintf(stderr, "Usage: %s [-v][rcontrib options] sender.rad receiver.rad [system.rad ..]\n", progname); return(1); }