--- ray/src/util/rfluxmtx.c 2016/02/02 18:02:32 2.34 +++ ray/src/util/rfluxmtx.c 2019/03/03 17:01:13 2.47 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rfluxmtx.c,v 2.34 2016/02/02 18:02:32 greg Exp $"; +static const char RCSid[] = "$Id: rfluxmtx.c,v 2.47 2019/03/03 17:01:13 greg Exp $"; #endif /* * Calculate flux transfer matrix or matrices using rcontrib @@ -18,13 +18,10 @@ static const char RCSid[] = "$Id: rfluxmtx.c,v 2.34 20 #include "triangulate.h" #include "platform.h" -#ifdef getc_unlocked /* avoid horrendous overhead of flockfile */ -#undef getc -#define getc getc_unlocked +#ifndef MAXRCARG +#define MAXRCARG 10000 #endif -#define MAXRCARG 512 - char *progname; /* global argv[0] */ int verbose = 0; /* verbose mode (< 0 no warnings) */ @@ -69,7 +66,7 @@ typedef struct { FVECT uva[2]; /* tangent axes */ int ntris; /* number of triangles */ struct ptri { - float afrac; /* fraction of total area */ + double afrac; /* fraction of total area */ short vndx[3]; /* vertex indices */ } tri[1]; /* triangle array (extends struct) */ } POLYTRIS; /* triangulated polygon */ @@ -143,6 +140,10 @@ oconv_command(int ac, char *av[]) if (ac-- <= 0) return(NULL); + if (verbose < 0) { /* turn off warnings */ + strcpy(cp, "-w- "); + cp += 4; + } while (ac-- > 0) { strcpy(cp, *av++); while (*cp) cp++; @@ -186,7 +187,7 @@ popen_arglist(char *av[], char *mode) return(popen(cmd, mode)); } -#ifdef _WIN32 +#if defined(_WIN32) || defined(_WIN64) /* Execute system command (Windows version) */ static int my_exec(char *av[]) @@ -384,7 +385,7 @@ finish_receiver(void) curparams.vup[1] = 1; } /* determine sample type/bin */ - if (tolower(curparams.hemis[0]) == 'u' | curparams.hemis[0] == '1') { + if ((tolower(curparams.hemis[0]) == 'u') | (curparams.hemis[0] == '1')) { sprintf(sbuf, "if(-Dx*%g-Dy*%g-Dz*%g,0,-1)", curparams.nrm[0], curparams.nrm[1], curparams.nrm[2]); binv = savqstr(sbuf); @@ -607,7 +608,7 @@ ssamp_poly(FVECT orig, SURF *sp, double x) sp->priv = (void *)ptp; } /* pick triangle by partial area */ - for (i = 0; i < ptp->ntris && x > ptp->tri[i].afrac; i++) + for (i = 0; i < ptp->ntris-1 && x > ptp->tri[i].afrac; i++) x -= ptp->tri[i].afrac; SDmultiSamp(samp2, 2, x/ptp->tri[i].afrac); samp2[0] *= samp2[1] = sqrt(samp2[1]); @@ -648,7 +649,11 @@ sample_origin(PARAMS *p, FVECT orig, const FVECT rdir, if (p->nsurfs > nall) { /* (re)allocate surface area cache */ if (projsa) free(projsa); projsa = (double *)malloc(sizeof(double)*p->nsurfs); - if (!projsa) return(0); + if (projsa == NULL) { + fputs(progname, stderr); + fputs(": out of memory in sample_origin!\n", stderr); + exit(1); + } nall = p->nsurfs; } /* compute projected areas */ @@ -656,7 +661,7 @@ sample_origin(PARAMS *p, FVECT orig, const FVECT rdir, projsa[i] = -DOT(sp->snrm, rdir) * sp->area; tarea += projsa[i] *= (double)(projsa[i] > FTINY); } - if (tarea <= FTINY) { /* wrong side of sender? */ + if (tarea < 0) { /* wrong side of sender? */ fputs(progname, stderr); fputs(": internal - sample behind all sender elements!\n", stderr); @@ -691,7 +696,7 @@ sample_uniform(PARAMS *p, int b, FILE *fp) duvw[2]*p->nrm[i] ; if (!sample_origin(p, orig_dir[0], orig_dir[1], samp3[0])) return(0); - if (fwrite(orig_dir, sizeof(FVECT), 2, fp) != 2) + if (putbinary(orig_dir, sizeof(FVECT), 2, fp) != 2) return(0); } return(1); @@ -721,7 +726,7 @@ sample_shirchiu(PARAMS *p, int b, FILE *fp) duvw[2]*p->nrm[i] ; if (!sample_origin(p, orig_dir[0], orig_dir[1], samp3[0])) return(0); - if (fwrite(orig_dir, sizeof(FVECT), 2, fp) != 2) + if (putbinary(orig_dir, sizeof(FVECT), 2, fp) != 2) return(0); } return(1); @@ -757,11 +762,13 @@ sample_reinhart(PARAMS *p, int b, FILE *fp) } while (n--) { /* stratified sampling */ SDmultiSamp(samp3, 3, (n+frandom())/sampcnt); + if (row >= RowMax-1) /* avoid crowding at zenith */ + samp3[1] *= samp3[1]; alt = (row+samp3[1])*RAH; azi = (2.*PI)*(col+samp3[2]-.5)/rnaz(row); duvw[2] = cos(alt); /* measured from horizon */ duvw[0] = tsin(azi)*duvw[2]; - duvw[1] = tcos(azi)*duvw[2]; + duvw[1] = -tcos(azi)*duvw[2]; duvw[2] = sqrt(1. - duvw[2]*duvw[2]); for (i = 3; i--; ) orig_dir[1][i] = -duvw[0]*p->udir[i] - @@ -769,7 +776,7 @@ sample_reinhart(PARAMS *p, int b, FILE *fp) duvw[2]*p->nrm[i] ; if (!sample_origin(p, orig_dir[0], orig_dir[1], samp3[0])) return(0); - if (fwrite(orig_dir, sizeof(FVECT), 2, fp) != 2) + if (putbinary(orig_dir, sizeof(FVECT), 2, fp) != 2) return(0); } return(1); @@ -820,7 +827,7 @@ sample_klems(PARAMS *p, int b, FILE *fp) duvw[2]*p->nrm[i] ; if (!sample_origin(p, orig_dir[0], orig_dir[1], samp2[0])) return(0); - if (fwrite(orig_dir, sizeof(FVECT), 2, fp) != 2) + if (putbinary(orig_dir, sizeof(FVECT), 2, fp) != 2) return(0); } return(1); @@ -868,7 +875,7 @@ prepare_sampler(void) curparams.udir[1] *= -1.; curparams.udir[2] *= -1.; } - if (tolower(curparams.hemis[0]) == 'u' | curparams.hemis[0] == '1') + if ((tolower(curparams.hemis[0]) == 'u') | (curparams.hemis[0] == '1')) curparams.sample_basis = sample_uniform; else if (tolower(curparams.hemis[0]) == 's' && tolower(curparams.hemis[1]) == 'c') @@ -947,7 +954,7 @@ add_surface(int st, const char *oname, FILE *fp) snew = (SURF *)malloc(sizeof(SURF) + sizeof(double)*(n-1)); if (snew == NULL) { fputs(progname, stderr); - fputs(": out of memory!\n", stderr); + fputs(": out of memory in add_surface!\n", stderr); exit(1); } strncpy(snew->sname, oname, sizeof(snew->sname)-1); @@ -1306,7 +1313,11 @@ main(int argc, char *argv[]) fputs(": -i, -I supported for pass-through only\n", stderr); return(1); } - fmtopt[2] = (sizeof(RREAL)==sizeof(double)) ? 'd' : 'f'; +#ifdef SMLFLT + fmtopt[2] = 'f'; +#else + fmtopt[2] = 'd'; +#endif if (sampcnt <= 0) sampcnt = 10000; } sprintf(sampcntbuf, "%d", sampcnt);