--- ray/src/rt/RcontribSimulManager.cpp 2024/11/06 18:28:52 2.6 +++ ray/src/rt/RcontribSimulManager.cpp 2024/12/10 00:38:59 2.10 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: RcontribSimulManager.cpp,v 2.6 2024/11/06 18:28:52 greg Exp $"; +static const char RCSid[] = "$Id: RcontribSimulManager.cpp,v 2.10 2024/12/10 00:38:59 greg Exp $"; #endif /* * RcontribSimulManager.cpp @@ -24,11 +24,6 @@ extern const char HDRSTR[]; extern const char BIGEND[]; extern const char FMTSTR[]; -int contrib = 0; // computing contributions? - -int xres = 0; // horizontal (scan) size -int yres = 0; // vertical resolution - // new/exclusive, overwrite if exists, or recover data int RSDOflags[] = {RDSwrite|RDSexcl|RDSextend, RDSwrite|RDSextend, RDSread|RDSwrite}; @@ -57,6 +52,19 @@ struct RowAssignment { uint32 ac; // accumulation count }; +// Get format identifier +const char * +formstr(int f) +{ + switch (f) { + case 'a': return("ascii"); + case 'f': return("float"); + case 'd': return("double"); + case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT); + } + return("unknown"); +} + // Our default data share function RdataShare * defDataShare(const char *name, RCOutputOp op, size_t siz) @@ -68,27 +76,36 @@ defDataShare(const char *name, RCOutputOp op, size_t s RcontribMod * NewRcMod(const char *prms, const char *binexpr, int ncbins) { - if (ncbins <= 0) return NULL; if (!prms) prms = ""; - if (!binexpr & (ncbins > 1)) { - error(INTERNAL, "missing bin expression"); + if ((ncbins > 1) & !binexpr) { + error(USER, "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; - } + if (ncbins < 1) ncbins = 1; + RcontribMod * mp = (RcontribMod *)ecalloc(1, sizeof(RcontribMod) + sizeof(DCOLORV)*(NCSAMP*ncbins-1) + strlen(prms)+1); - mp->params = strcpy((char *)(mp->cbin + ncbins*NCSAMP), prms); - if (binexpr) { + if (binexpr) { // check bin expression mp->binv = eparse(const_cast(binexpr)); - CHECK(mp->binv->type==NUM, WARNING, "constant bin expression"); + if (mp->binv->type == NUM) { // constant expression (0)? + if ((int)(evalue(mp->binv) + .5) > 0) { + sprintf(errmsg, "illegal positive constant for bin (%s)", + binexpr); + error(USER, errmsg); + } + if (ncbins > 1) { + sprintf(errmsg, "bad bin count (%d should be 1)", ncbins); + error(USER, errmsg); + } + epfree(mp->binv, true); + mp->binv = NULL; + prms = ""; + ncbins = 1; + } } + mp->params = strcpy((char *)(mp->cbin + ncbins*NCSAMP), prms); mp->nbins = ncbins; return mp; } @@ -163,7 +180,7 @@ RcontribSimulManager::RctCall(RAY *r, void *cd) } 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 @@ -193,16 +210,20 @@ bool RcontribSimulManager::AddModifier(const char *modn, const char *outspec, const char *prms, const char *binval, int bincnt) { - if (!modn | !outspec | (bincnt <= 0) || !*modn | !*outspec) { + if (!modn | !outspec || !*modn | !*outspec) { error(WARNING, "ignoring bad call to AddModifier()"); return false; } if (!nChan) { // initial call? + if ((xres < 0) | (yres <= 0)) { + error(USER, "xres, yres must be set before first modifier"); + return false; + } if (!SetDataFormat(dtyp)) return false; nChan = NCSAMP; } else if (nChan != NCSAMP) { - error(INTERNAL, "number of spectral channels must be fixed"); + error(USER, "number of spectral channels must be fixed"); return false; } if (Ready()) { @@ -225,7 +246,7 @@ RcontribSimulManager::AddModifier(const char *modn, co const int binndx = hasFormat(outspec, "diouxX"); int bin0 = 0; char fnbuf[512]; - if (!modndx | (modndx > binndx)) + if (!modndx || (binndx > 0) & (modndx > binndx)) sprintf(fnbuf, outspec, bin0, modn); else sprintf(fnbuf, outspec, modn, bin0); @@ -254,11 +275,11 @@ RcontribSimulManager::AddModifier(const char *modn, co mp->opl = op; // first (maybe only) output channel if (modndx) // remember modifier if part of name op->omod = lp->key; - if (binndx > 0) { // append output image/bin list + if (binndx) { // append output image/bin list op->rowBytes += dsiz; op->obin = bin0; for (bincnt = 1; bincnt < mp->nbins; bincnt++) { - if (!modndx | (modndx > binndx)) + if (!modndx || (binndx > 0) & (modndx > binndx)) sprintf(fnbuf, outspec, bin0+bincnt, modn); else sprintf(fnbuf, outspec, modn, bin0+bincnt); @@ -277,7 +298,7 @@ RcontribSimulManager::AddModifier(const char *modn, co op->rowBytes += dsiz; } } else // else send all results to this channel - op->rowBytes += bincnt*dsiz; + op->rowBytes += mp->nbins*dsiz; return true; } @@ -392,7 +413,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); } @@ -430,8 +451,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); @@ -485,7 +506,7 @@ RcontribOutput::CheckHeader(const RcontribSimulManager } // 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); @@ -500,9 +521,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());