--- ray/src/rt/rcontrib.c 2018/11/13 19:58:33 2.34 +++ ray/src/rt/rcontrib.c 2024/10/23 23:51:20 2.46 @@ -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.46 2024/10/23 23:51:20 greg Exp $"; #endif /* * Accumulate ray contributions for a set of materials @@ -12,8 +12,6 @@ static const char RCSid[] = "$Id: rcontrib.c,v 2.34 20 #include "otypes.h" #include "source.h" -char *shm_boundary = NULL; /* boundary of shared memory */ - CUBE thescene; /* our scene */ OBJECT nsceneobjs; /* number of objects in our scene */ @@ -68,13 +66,13 @@ RNUMBER lastdone = 0; /* last ray output */ static void trace_contrib(RAY *r); /* our trace callback */ -static void mcfree(void *p) { epfree((*(MODCONT *)p).binv); free(p); } +static void mcfree(void *p) { epfree((*(MODCONT *)p).binv,1); free(p); } LUTAB modconttab = LU_SINIT(NULL,mcfree); /* modifier lookup table */ /************************** INITIALIZATION ROUTINES ***********************/ -char * +const char * formstr( /* return format identifier */ int f ) @@ -83,7 +81,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"); } @@ -93,23 +91,34 @@ formstr( /* return format identifier */ MODCONT * addmodifier(char *modn, char *outf, char *prms, char *binv, int bincnt) { - LUENT *lep = lu_find(&modconttab,modn); - MODCONT *mp; - EPNODE *ebinv; - int i; - + static int lastNCS = 0; + LUENT *lep = lu_find(&modconttab,modn); + MODCONT *mp; + EPNODE *ebinv; + int i; + + if (!lastNCS) + lastNCS = NCSAMP; + else if (NCSAMP != lastNCS) + error(INTERNAL, + "number of spectral samples must be set before first modifier"); if (lep->data != NULL) { 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 +138,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 +147,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 +163,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); } @@ -192,11 +230,8 @@ rcinit(void) if (nproc > MAXPROCESS) sprintf(errmsg, "too many processes requested -- reducing to %d", nproc = MAXPROCESS); - if (nproc > 1) { - preload_objs(); /* preload auxiliary data */ - /* set shared memory boundary */ - shm_boundary = strcpy((char *)malloc(16), "SHM_BOUNDARY"); - } + if (nproc > 1) + cow_memshare(); /* preload auxiliary data */ trace = trace_contrib; /* set up trace call-back */ for (i = 0; i < nsources; i++) /* tracing to sources as well */ source[i].sflags |= SFOLLOW; @@ -239,7 +274,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 +300,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 +320,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 +357,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 +401,7 @@ rcontrib(void) } done_contrib(); /* accumulate/output */ ++lastdone; - if (raysleft && !--raysleft) + if (!morays()) break; /* preemptive EOI */ } if (nchild != -1 && (accumulate <= 0) | (account < accumulate)) {