--- ray/src/rt/rcontrib.c 2018/11/13 19:58:33 2.34 +++ ray/src/rt/rcontrib.c 2023/11/15 18:02:53 2.43 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rcontrib.c,v 2.34 2018/11/13 19:58:33 greg Exp $"; +static const char RCSid[] = "$Id: rcontrib.c,v 2.43 2023/11/15 18:02:53 greg Exp $"; #endif /* * Accumulate ray contributions for a set of materials @@ -74,7 +74,7 @@ LUTAB modconttab = LU_SINIT(NULL,mcfree); /* modifier /************************** INITIALIZATION ROUTINES ***********************/ -char * +const char * formstr( /* return format identifier */ int f ) @@ -83,7 +83,7 @@ formstr( /* return format identifier */ case 'a': return("ascii"); case 'f': return("float"); case 'd': return("double"); - case 'c': return(COLRFMT); + case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT); } return("unknown"); } @@ -102,14 +102,19 @@ addmodifier(char *modn, char *outf, char *prms, char * sprintf(errmsg, "duplicate modifier '%s'", modn); error(USER, errmsg); } - if (nmods >= MAXMODLIST) { - sprintf(errmsg, "too many modifiers (%d limit)", MAXMODLIST); - error(INTERNAL, errmsg); - } if (!strcmp(modn, VOIDID)) { sprintf(errmsg, "cannot track '%s' modifier", VOIDID); error(USER, errmsg); } + if (nmods >= modasiz) { /* need bigger modifier array */ + modasiz += modasiz/2 + 64; + if (modname == NULL) + modname = (char **)malloc(modasiz*sizeof(char *)); + else + modname = (char **)realloc(modname, modasiz*sizeof(char *)); + if (modname == NULL) + error(SYSTEM, "Out of memory in addmodifier()"); + } modname[nmods++] = modn; /* XXX assumes static string */ lep->key = modn; /* XXX assumes static string */ if (binv == NULL) @@ -129,7 +134,7 @@ addmodifier(char *modn, char *outf, char *prms, char * error(USER, errmsg); } /* initialize results holder */ - mp = (MODCONT *)malloc(sizeof(MODCONT)+sizeof(DCOLOR)*(bincnt-1)); + mp = (MODCONT *)malloc(mcsize(bincnt)); if (mp == NULL) error(SYSTEM, "out of memory in addmodifier"); mp->outspec = outf; /* XXX assumes static string */ @@ -138,7 +143,7 @@ addmodifier(char *modn, char *outf, char *prms, char * mp->binv = ebinv; mp->bin0 = 0; mp->nbins = bincnt; - memset(mp->cbin, 0, sizeof(DCOLOR)*bincnt); + memset(mp->cbin, 0, DCOLORSIZ*bincnt); /* figure out starting bin */ while (!getostream(mp->outspec, mp->modname, mp->bin0, 1)) mp->bin0++; @@ -154,31 +159,60 @@ addmodifier(char *modn, char *outf, char *prms, char * void addmodfile(char *fname, char *outf, char *prms, char *binv, int bincnt) { - char *mname[MAXMODLIST]; - int i; - /* find the file & store strings */ - i = wordfile(mname, MAXMODLIST, getpath(fname, getrlibpath(), R_OK)); - if (i < 0) { - sprintf(errmsg, "cannot find modifier file '%s'", fname); + char *path = getpath(fname, getrlibpath(), R_OK); + char mod[MAXSTR]; + FILE *fp; + + if (path == NULL || (fp = fopen(path, "r")) == NULL) { + if (path == NULL) + sprintf(errmsg, "cannot find modifier file '%s'", fname); + else + sprintf(errmsg, "cannot load modifier file '%s'", path); error(SYSTEM, errmsg); } - if (i >= MAXMODLIST-1) { - sprintf(errmsg, "too many modifiers (%d limit) in file '%s'", - MAXMODLIST-1, fname); - error(INTERNAL, errmsg); + while (fgetword(mod, sizeof(mod), fp) != NULL) + addmodifier(savqstr(mod), outf, prms, binv, bincnt); + fclose(fp); +} + + +/* Check if we have any more rays left (and report progress) */ +int +morays(void) +{ + static RNUMBER total_rays; + static time_t tstart, last_report; + time_t tnow; + + if (!raysleft) + return(1); /* unknown total, so nothing to do or say */ + + if (report_intvl > 0 && (tnow = time(0)) >= last_report+report_intvl) { + if (!total_rays) { + total_rays = raysleft; + tstart = tnow; + } else { + sprintf(errmsg, "%.2f%% done after %.3f hours\n", + 100.-100.*raysleft/total_rays, + (1./3600.)*(tnow - tstart)); + eputs(errmsg); + } + last_report = tnow; } - for (i = 0; mname[i]; i++) /* add each one */ - addmodifier(mname[i], outf, prms, binv, bincnt); + return(--raysleft); } +/* Quit program */ void -quit( /* quit program */ +quit( int code ) { if (nchild > 0) /* close children if any */ end_children(code != 0); + else if (nchild < 0) + _exit(code); /* avoid flush() in child */ exit(code); } @@ -239,7 +273,9 @@ trace_contrib(RAY *r) MODCONT *mp; double bval; int bn; - RREAL contr[3]; + SCOLOR contr; + DCOLORV *dvp; + int i; if (r->ro == NULL || r->ro->omod == OVOID) return; @@ -263,8 +299,10 @@ trace_contrib(RAY *r) } raycontrib(contr, r, PRIMARY); /* compute coefficient */ if (contrib) - multcolor(contr, r->rcol); /* -> contribution */ - addcolor(mp->cbin[bn], contr); + smultscolor(contr, r->rcol); /* -> contribution */ + dvp = mcbin(mp, bn); + for (i = 0; i < NCSAMP; i++) /* add it in */ + *dvp++ += contr[i]; } @@ -281,7 +319,7 @@ eval_irrad(FVECT org, FVECT dir) thisray.rmax = 0.0; rayorigin(&thisray, PRIMARY, NULL, NULL); /* pretend we hit surface */ - thisray.rxt = thisray.rmt = thisray.rot = 1e-5; + thisray.rxt = thisray.rot = 1e-5; thisray.rod = 1.0; VCOPY(thisray.ron, dir); VSUM(thisray.rop, org, dir, 1e-4); @@ -318,7 +356,7 @@ done_contrib(void) for (i = 0; i < nmods; i++) { /* output records & clear */ mp = (MODCONT *)lu_find(&modconttab,modname[i])->data; mod_output(mp); - memset(mp->cbin, 0, sizeof(DCOLOR)*mp->nbins); + memset(mp->cbin, 0, DCOLORSIZ*mp->nbins); } end_record(); /* end lines & flush if time */ @@ -362,7 +400,7 @@ rcontrib(void) } done_contrib(); /* accumulate/output */ ++lastdone; - if (raysleft && !--raysleft) + if (!morays()) break; /* preemptive EOI */ } if (nchild != -1 && (accumulate <= 0) | (account < accumulate)) {