--- ray/src/rt/RcontribSimulManager.cpp 2024/10/29 00:36:54 2.1 +++ ray/src/rt/RcontribSimulManager.cpp 2024/11/06 19:45:59 2.7 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: RcontribSimulManager.cpp,v 2.1 2024/10/29 00:36:54 greg Exp $"; +static const char RCSid[] = "$Id: RcontribSimulManager.cpp,v 2.7 2024/11/06 19:45:59 greg Exp $"; #endif /* * RcontribSimulManager.cpp @@ -24,9 +24,6 @@ extern const char HDRSTR[]; extern const char BIGEND[]; extern const char FMTSTR[]; -extern int contrib; /* computing contributions? */ -extern int lim_dist; /* limit distance? */ - // new/exclusive, overwrite if exists, or recover data int RSDOflags[] = {RDSwrite|RDSexcl|RDSextend, RDSwrite|RDSextend, RDSread|RDSwrite}; @@ -38,7 +35,7 @@ static const char ROWZEROSTR[] = "NROWS=00000000000000 struct RcontribMod { RcontribOutput * opl; // pointer to first output channel char * params; // parameters string - EPNODE * binv; // bin expression + EPNODE * binv; // bin expression (NULL if 1 bin) int nbins; // bin count this modifier int coffset; // column offset in bytes DCOLORV cbin[1]; // bin accumulator (extends struct) @@ -49,7 +46,7 @@ struct RcontribMod { } }; -// used to assign record calc to child +// Struct used to assign record calculation to child struct RowAssignment { uint32 row; // row to do uint32 ac; // accumulation count @@ -68,15 +65,25 @@ NewRcMod(const char *prms, const char *binexpr, int nc { if (ncbins <= 0) return NULL; if (!prms) prms = ""; - if (!binexpr | (ncbins == 1)) - binexpr = "0"; - + if (!binexpr & (ncbins > 1)) { + error(INTERNAL, "missing bin expression"); + return NULL; + } + if (ncbins == 1) { // shouldn't have bin expression? + if (binexpr && strcmp(binexpr, "0")) + error(WARNING, "ignoring non-zero expression for single bin"); + prms = ""; + binexpr = NULL; + } RcontribMod * mp = (RcontribMod *)ecalloc(1, sizeof(RcontribMod) + sizeof(DCOLORV)*(NCSAMP*ncbins-1) + strlen(prms)+1); mp->params = strcpy((char *)(mp->cbin + ncbins*NCSAMP), prms); - mp->binv = eparse(const_cast(binexpr)); + if (binexpr) { + mp->binv = eparse(const_cast(binexpr)); + CHECK(mp->binv->type==NUM, WARNING, "constant bin expression"); + } mp->nbins = ncbins; return mp; } @@ -86,7 +93,8 @@ void FreeRcMod(void *p) { if (!p) return; - epfree((*(RcontribMod *)p).binv, true); + EPNODE * bep = (*(RcontribMod *)p).binv; + if (bep) epfree(bep, true); efree(p); } @@ -133,20 +141,24 @@ RcontribSimulManager::RctCall(RAY *r, void *cd) if (!mp) return 0; // not in our modifier list - worldfunc(RCCONTEXT, r); // compute bin # - set_eparams(mp->params); - double bval = evalue(mp->binv); - if (bval <= -.5) - return 0; // silently ignore negative bin index - DCOLORV * dvp = (*mp)[int(bval + .5)]; + int bi = 0; // get bin index + if (mp->binv) { + worldfunc(RCCONTEXT, r); + set_eparams(mp->params); + double bval = evalue(mp->binv); + if (bval <= -.5) + return 0; // silently ignore negative bin index + bi = int(bval + .5); + } + DCOLORV * dvp = (*mp)[bi]; if (!dvp) { - sprintf(errmsg, "bad bin number for '%s' (%.1f ignored)", mname, bval); + sprintf(errmsg, "bad bin number for '%s' (%d ignored)", mname, bi); error(WARNING, errmsg); return 0; } SCOLOR contr; raycontrib(contr, r, PRIMARY); // compute coefficient - if (contrib) + if (rcp->HasFlag(RCcontrib)) smultscolor(contr, r->rcol); // -> value contribution for (int i = 0; i < NCSAMP; i++) *dvp++ += contr[i]; // accumulate color/spectrum @@ -181,6 +193,10 @@ RcontribSimulManager::AddModifier(const char *modn, co return false; } if (!nChan) { // initial call? + if ((xres < 0) | (yres <= 0)) { + error(INTERNAL, "xres, yres must be set before first modifier"); + return false; + } if (!SetDataFormat(dtyp)) return false; nChan = NCSAMP; @@ -287,19 +303,16 @@ RcontribSimulManager::AddModFile(const char *modfn, co return true; } -// Run through current list of output struct's -int -RcontribSimulManager::GetOutputs(RoutputShareF *osF, void *cd) const +// call-back to check if modifier has been loaded +static int +checkModExists(const LUENT *lp, void *p) { - int cnt = 0; + if (modifier(lp->key) != OVOID) + return 1; - for (const RcontribOutput *op = outList; op; op = op->next) { - int rv = 1; - if (osF && (rv = (*osF)(op, cd)) < 0) - return rv; - cnt += rv; - } - return cnt; + sprintf(errmsg, "tracked modifier '%s' not found in main scene", lp->key); + error(WARNING, errmsg); + return 0; } // Prepare output channels and return # completed rows @@ -310,6 +323,13 @@ RcontribSimulManager::PrepOutput() error(INTERNAL, "PrepOutput() called before octree & modifiers assigned"); return -1; } + if (!cdsF) { + error(INTERNAL, "missing RdataShare constructor call (*cdsF)"); + return -1; + } + if (lu_doall(&modLUT, checkModExists, NULL) < 0) + return -1; + int remWarnings = 20; for (RcontribOutput *op = outList; op; op = op->next) { if (op->rData) { @@ -341,11 +361,6 @@ RcontribSimulManager::PrepOutput() !op->rData->Resize(op->begData + op->nRows*op->rowBytes)) return -1; // calls error() for us } - if (lim_dist) // XXX where else to put this? - rtFlags |= RTlimDist; - else - rtFlags &= ~RTlimDist; - rowsDone.NewBitMap(outList->nRows); // create row completion map rowsDone.ClearBits(0, rInPos, true); return rInPos; @@ -376,7 +391,7 @@ RcontribOutput::NewHeader(const RcontribSimulManager * strcpy(hdr+begData, ROWZEROSTR); rowCountPos = begData+LNROWSTR; begData += sizeof(ROWZEROSTR)-1; - if (!xres | (rowBytes > esiz)) { + if (!rcp->xres | (rowBytes > esiz)) { sprintf(hdr+begData, "NCOLS=%d\n", int(rowBytes/esiz)); begData += strlen(hdr+begData); } @@ -414,8 +429,8 @@ RcontribOutput::NewHeader(const RcontribSimulManager * hdr[begData++] = ' '; hdr[begData++] = '\n'; // EOL for data format hdr[begData++] = '\n'; // end of nominal header - if ((xres > 0) & (rowBytes == esiz)) { // tack on resolution string? - sprintf(hdr+begData, PIXSTDFMT, yres, xres); + if ((rcp->xres > 0) & (rowBytes == esiz)) { // tack on resolution string? + sprintf(hdr+begData, PIXSTDFMT, rcp->yres, rcp->xres); begData += strlen(hdr+begData); } return rData->ReleaseMemory(hdr, RDSwrite); @@ -461,14 +476,15 @@ RcontribOutput::CheckHeader(const RcontribSimulManager return -1; } // check format - if (!(cp = findArgs(hdr, FMTSTR, begData)) || strcmp(cp, formstr(etyp))) { + if (!(cp = findArgs(hdr, FMTSTR, begData)) || + strncmp(cp, formstr(etyp), strlen(formstr(etyp)))) { sprintf(errmsg, "expected %s%s in '%s'", FMTSTR, formstr(etyp), GetName()); error(USER, errmsg); return -1; } // check #columns if (((cp = findArgs(hdr, "NCOLS=", begData)) && atoi(cp)*esiz != rowBytes) || - !xres | (rowBytes > esiz)) { + !rcp->xres | (rowBytes > esiz)) { sprintf(errmsg, "expected NCOLS=%d in '%s'", int(rowBytes/esiz), GetName()); error(USER, errmsg); @@ -483,9 +499,9 @@ RcontribOutput::CheckHeader(const RcontribSimulManager rowCountPos = cp - hdr; int rlast = atoi(cp); begData++; // advance past closing EOL - if ((xres > 0) & (rowBytes == esiz)) { // check/skip resolution string? + if ((rcp->xres > 0) & (rowBytes == esiz)) { // check/skip resolution string? char rbuf[64]; - sprintf(rbuf, PIXSTDFMT, yres, xres); + sprintf(rbuf, PIXSTDFMT, rcp->yres, rcp->xres); int rlen = strlen(rbuf); if (strncmp(rbuf, hdr+begData, rlen)) { sprintf(errmsg, "bad resolution string in '%s'", GetName()); @@ -650,7 +666,8 @@ RcontribSimulManager::GetChild(bool forceWait) FD_ISSET(kid[n].w, &writeset) | FD_ISSET(kid[n].w, &errset)) { // update output row counts - UpdateRowsDone(kidRow[n]); + if (!FD_ISSET(kid[n].w, &errset)) + UpdateRowsDone(kidRow[n]); kidRow[n] = -1; // flag it available pn = n; } @@ -734,7 +751,6 @@ RcontribSimulManager::StartKids(int n2go) close(kid[nkids].w); free(kid); free(kidRow); kid = NULL; kidRow = NULL; - rowsDone.NewBitMap(0); RunChild(); // should never return _exit(1); } @@ -783,7 +799,7 @@ RcontribSimulManager::SetThreadCount(int nt) return 0; } if (nt < 0) - return nkids; + return NThreads(); if (!nt) nt = GetNCores(); int status = 0; if (nt == 1) @@ -796,5 +812,5 @@ RcontribSimulManager::SetThreadCount(int nt) sprintf(errmsg, "non-zero (%d) status from child", status); error(WARNING, errmsg); } - return nkids; + return NThreads(); }