diff --git a/src/rt/RcontribSimulManager.cpp b/src/rt/RcontribSimulManager.cpp index fb175cf3..9844d992 100644 --- a/src/rt/RcontribSimulManager.cpp +++ b/src/rt/RcontribSimulManager.cpp @@ -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.7 2024/11/06 19:45: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}; @@ -163,7 +158,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 @@ -198,6 +193,10 @@ RcontribSimulManager::AddModifier(const char *modn, const char *outspec, 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; @@ -392,7 +391,7 @@ RcontribOutput::NewHeader(const RcontribSimulManager *rcp) 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 +429,8 @@ RcontribOutput::NewHeader(const RcontribSimulManager *rcp) 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 +484,7 @@ RcontribOutput::CheckHeader(const RcontribSimulManager *rcp) } // 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 +499,9 @@ RcontribOutput::CheckHeader(const RcontribSimulManager *rcp) 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()); diff --git a/src/rt/RcontribSimulManager.h b/src/rt/RcontribSimulManager.h index 4d06ecdc..4d5a6e70 100644 --- a/src/rt/RcontribSimulManager.h +++ b/src/rt/RcontribSimulManager.h @@ -1,4 +1,4 @@ -/* RCSid $Id: RcontribSimulManager.h,v 2.5 2024/11/06 18:28:52 greg Exp $ */ +/* RCSid $Id: RcontribSimulManager.h,v 2.6 2024/11/06 19:45:59 greg Exp $ */ /* * RcontribSimulManager.h * @@ -25,10 +25,6 @@ extern char RCCONTEXT[]; // global rcontrib context -extern int contrib; // computing contributions? - -extern int xres, yres; // global resolution settings - class RcontribSimulManager; // need forward decl /// Shared data object for record output (includes header; may be write-only) @@ -125,18 +121,20 @@ extern lut_free_t FreeRcMod; * * 1) Call LoadOctree(), then alter the header as desired * 2) Set number of spectral samples (NCSAMP) and call SetDataFormat() - * 3) Call AddModifier() and AddModFile() to indicate tracked modifiers - * 4) Set outOp and cdsF according to desired output/recovery - * 5) Call PrepOutput() to open output channels - * 6) Call SetThreadCount() to fork children if desired - * 7) Set accum to the number of ray samples per record - * 8) Call ComputeRecord() with accum ray samples - * 9) Continue until GetRowMax() records have been sent - * 10) Call Cleanup() + * 3) Set xres and yres to desired dimensions (xres>0 for picture output) + * 4) Call AddModifier() and AddModFile() to indicate tracked modifiers + * 5) Set outOp and cdsF according to desired output/recovery + * 6) Set desired computation flags via SetFlag() + * 7) Call PrepOutput() to open output channels + * 8) Call SetThreadCount() to fork children if desired + * 9) Set accum to the number of ray samples per record + * 10) Call ComputeRecord() with accum ray samples + * 11) Continue until GetRowMax() records have been sent + * 12) Call Cleanup() * * The order of some of these calls may be changed. Technically, the octree * may be loaded anytime before PrepOutput() is called. Also, SetThreadCount() - * may be called anytime after PrepOutput() and interleaved with + * may be called anytime *after* PrepOutput(), and may be interleaved with * calls to ComputeRecord(). The accum setting may be changed at any time. * Finally, it is possible to restart the output using ResetRow(), and * a zero argument will rewind to the beginning, whence all records @@ -166,7 +164,8 @@ typedef RdataShare * RcreateDataShareF(const char *name, RCOutputOp op, size_t s extern RcreateDataShareF defDataShare; /// Modifiable ray-tracing flags for rcontrib -#define RCmask (RTlimDist|RTimmIrrad) +#define RCcontrib (RTmask+1) // compute contributions? (r.t. coefficients) +#define RCmask (RTlimDist|RTimmIrrad|RCcontrib) /// rcontrib-like simulation manager (at most one such object) class RcontribSimulManager : protected RtraceSimulManager { @@ -190,6 +189,7 @@ class RcontribSimulManager : protected RtraceSimulManager { public: RCOutputOp outOp; // output operation RcreateDataShareF * cdsF; // data share creator + int xres, yres; // output (picture) size uint32 accum; // # rays to accumulate per record RcontribSimulManager(const char *octn = NULL) : RtraceSimulManager(NULL, NULL, octn) { @@ -208,6 +208,7 @@ class RcontribSimulManager : protected RtraceSimulManager { SetTraceCall(&RctCall, this); outOp = RCOnew; cdsF = &defDataShare; + xres = yres = 0; accum = 1; } ~RcontribSimulManager() { diff --git a/src/rt/rxcmain.cpp b/src/rt/rxcmain.cpp index b07aa38b..6f948c09 100644 --- a/src/rt/rxcmain.cpp +++ b/src/rt/rxcmain.cpp @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: rxcmain.cpp,v 2.5 2024/10/30 19:53:37 greg Exp $"; +static const char RCSid[] = "$Id: rxcmain.cpp,v 2.6 2024/11/06 19:45:59 greg Exp $"; #endif /* * rxcmain.c - main for rxcontrib ray contribution tracer @@ -41,14 +41,15 @@ static void printdefaults(void) /* print default values to stdout */ { printf("-c %-5d\t\t\t# accumulated rays per record\n", myRCmanager.accum); - printf("-V%c\t\t\t\t# output %s\n", contrib ? '+' : '-', - contrib ? "contributions" : "coefficients"); + printf(myRCmanager.HasFlag(RCcontrib) ? + "-V+\t\t\t\t# output contributions" : + "-V-\t\t\t\t# output coefficients"); if (myRCmanager.HasFlag(RTimmIrrad)) printf("-I+\t\t\t\t# immediate irradiance on\n"); printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc); - if (xres > 0) - printf("-x %-9d\t\t\t# x resolution\n", xres); - printf("-y %-9d\t\t\t# y resolution\n", yres); + if (myRCmanager.xres > 0) + printf("-x %-9d\t\t\t# x resolution\n", myRCmanager.xres); + printf("-y %-9d\t\t\t# y resolution\n", myRCmanager.yres); printf(myRCmanager.HasFlag(RTlimDist) ? "-ld+\t\t\t\t# limit distance on\n" : "-ld-\t\t\t\t# limit distance off\n"); @@ -218,15 +219,17 @@ main(int argc, char *argv[]) nproc = 1; break; case 'V': /* output contributions? */ - check_bool(2,contrib); + rval = myRCmanager.HasFlag(RCcontrib); + check_bool(2,rval); + myRCmanager.SetFlag(RCcontrib, rval); break; case 'x': /* x resolution */ check(2,"i"); - xres = atoi(argv[++i]); + myRCmanager.xres = atoi(argv[++i]); break; case 'y': /* y resolution */ check(2,"i"); - yres = atoi(argv[++i]); + myRCmanager.yres = atoi(argv[++i]); break; case 'w': /* warnings on/off */ rval = (erract[WARNING].pf != NULL);