ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RcontribSimulManager.cpp
(Generate patch)

Comparing ray/src/rt/RcontribSimulManager.cpp (file contents):
Revision 2.2 by greg, Tue Oct 29 19:47:19 2024 UTC vs.
Revision 2.11 by greg, Thu Jan 2 16:16:49 2025 UTC

# Line 24 | Line 24 | extern const char      HDRSTR[];
24   extern const char       BIGEND[];
25   extern const char       FMTSTR[];
26  
27 int     contrib = 0;                    // computing contributions?
28
29 int     xres = 0;                       // horizontal (scan) size
30 int     yres = 0;                       // vertical resolution
31
27   // new/exclusive, overwrite if exists, or recover data
28   int     RSDOflags[] = {RDSwrite|RDSexcl|RDSextend, RDSwrite|RDSextend,
29                                  RDSread|RDSwrite};
# Line 40 | Line 35 | static const char      ROWZEROSTR[] = "NROWS=00000000000000
35   struct RcontribMod {
36          RcontribOutput *        opl;            // pointer to first output channel
37          char *                  params;         // parameters string
38 <        EPNODE *                binv;           // bin expression
38 >        EPNODE *                binv;           // bin expression (NULL if 1 bin)
39          int                     nbins;          // bin count this modifier
40          int                     coffset;        // column offset in bytes
41          DCOLORV                 cbin[1];        // bin accumulator (extends struct)
# Line 57 | Line 52 | struct RowAssignment {
52          uint32                  ac;             // accumulation count
53   };
54  
55 + // Get format identifier
56 + const char *
57 + formstr(int f)
58 + {
59 +        switch (f) {
60 +        case 'a': return("ascii");
61 +        case 'f': return("float");
62 +        case 'd': return("double");
63 +        case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT);
64 +        }
65 +        return("unknown");
66 + }
67 +
68   // Our default data share function
69   RdataShare *
70   defDataShare(const char *name, RCOutputOp op, size_t siz)
# Line 68 | Line 76 | defDataShare(const char *name, RCOutputOp op, size_t s
76   RcontribMod *
77   NewRcMod(const char *prms, const char *binexpr, int ncbins)
78   {
71        if (ncbins <= 0) return NULL;
79          if (!prms) prms = "";
80 <        if (!binexpr | (ncbins == 1))
81 <                binexpr = "0";
82 <
80 >        if ((ncbins > 1) & !binexpr) {
81 >                error(USER, "missing bin expression");
82 >                return NULL;
83 >        }
84 >        if (ncbins < 1) ncbins = 1;
85 >        
86          RcontribMod *   mp = (RcontribMod *)ecalloc(1, sizeof(RcontribMod) +
87                                                  sizeof(DCOLORV)*(NCSAMP*ncbins-1) +
88                                                  strlen(prms)+1);
89  
90 +        if (binexpr) {                          // get/check bin expression
91 +                mp->binv = eparse(const_cast<char *>(binexpr));
92 +                if (mp->binv->type == NUM) {    // constant expression (0)?
93 +                        if ((int)evalue(mp->binv) != 0) {
94 +                                sprintf(errmsg, "illegal non-zero constant for bin (%s)",
95 +                                                binexpr);
96 +                                error(USER, errmsg);
97 +                        }
98 +                        if (ncbins > 1) {
99 +                                sprintf(errmsg, "bad bin count (%d should be 1)", ncbins);
100 +                                error(USER, errmsg);
101 +                        }
102 +                        epfree(mp->binv, true);
103 +                        mp->binv = NULL;
104 +                        prms = "";
105 +                        ncbins = 1;
106 +                }
107 +        }
108          mp->params = strcpy((char *)(mp->cbin + ncbins*NCSAMP), prms);
81        mp->binv = eparse(const_cast<char *>(binexpr));
109          mp->nbins = ncbins;
110          return mp;
111   }
# Line 88 | Line 115 | void
115   FreeRcMod(void *p)
116   {
117          if (!p) return;
118 <        epfree((*(RcontribMod *)p).binv, true);
118 >        EPNODE *        bep = (*(RcontribMod *)p).binv;
119 >        if (bep) epfree(bep, true);
120          efree(p);
121   }
122  
# Line 135 | Line 163 | RcontribSimulManager::RctCall(RAY *r, void *cd)
163          if (!mp)
164                  return 0;               // not in our modifier list
165  
166 <        worldfunc(RCCONTEXT, r);        // compute bin #
167 <        set_eparams(mp->params);
168 <        double          bval = evalue(mp->binv);
169 <        if (bval <= -.5)
170 <                return 0;       // silently ignore negative bin index
171 <        DCOLORV *       dvp = (*mp)[int(bval + .5)];
166 >        int                     bi = 0; // get bin index
167 >        if (mp->binv) {
168 >                worldfunc(RCCONTEXT, r);
169 >                set_eparams(mp->params);
170 >                double          bval = evalue(mp->binv);
171 >                if (bval <= -.5)
172 >                        return 0;       // silently ignore negative bin index
173 >                bi = int(bval + .5);
174 >        }
175 >        DCOLORV *       dvp = (*mp)[bi];
176          if (!dvp) {
177 <                sprintf(errmsg, "bad bin number for '%s' (%.1f ignored)", mname, bval);
177 >                sprintf(errmsg, "bad bin number for '%s' (%d ignored)", mname, bi);
178                  error(WARNING, errmsg);
179                  return 0;
180          }
181          SCOLOR          contr;
182          raycontrib(contr, r, PRIMARY);          // compute coefficient
183 <        if (contrib)
183 >        if (rcp->HasFlag(RCcontrib))
184                  smultscolor(contr, r->rcol);    // -> value contribution
185 +
186          for (int i = 0; i < NCSAMP; i++)
187                  *dvp++ += contr[i];             // accumulate color/spectrum
188          return 1;
# Line 178 | Line 211 | bool
211   RcontribSimulManager::AddModifier(const char *modn, const char *outspec,
212                                  const char *prms, const char *binval, int bincnt)
213   {
214 <        if (!modn | !outspec | (bincnt <= 0) || !*modn | !*outspec) {
214 >        if (!modn | !outspec || !*modn | !*outspec) {
215                  error(WARNING, "ignoring bad call to AddModifier()");
216                  return false;
217          }
218          if (!nChan) {                           // initial call?
219 +                if ((xres < 0) | (yres <= 0)) {
220 +                        error(USER, "xres, yres must be set before first modifier");
221 +                        return false;
222 +                }
223                  if (!SetDataFormat(dtyp))
224                          return false;
225                  nChan = NCSAMP;
226          } else if (nChan != NCSAMP) {
227 <                error(INTERNAL, "number of spectral channels must be fixed");
227 >                error(USER, "# spectral channels must be fixed in AddModifier()");
228                  return false;
229          }
230          if (Ready()) {
# Line 210 | Line 247 | RcontribSimulManager::AddModifier(const char *modn, co
247          const int       binndx = hasFormat(outspec, "diouxX");
248          int             bin0 = 0;
249          char            fnbuf[512];
250 <        if (!modndx | (modndx > binndx))
250 >        if (!modndx || (binndx > 0) & (modndx > binndx))
251                  sprintf(fnbuf, outspec, bin0, modn);
252          else
253                  sprintf(fnbuf, outspec, modn, bin0);
# Line 239 | Line 276 | RcontribSimulManager::AddModifier(const char *modn, co
276          mp->opl = op;                   // first (maybe only) output channel
277          if (modndx)                     // remember modifier if part of name
278                  op->omod = lp->key;
279 <        if (binndx > 0) {               // append output image/bin list
279 >        if (binndx) {                   // append output image/bin list
280                  op->rowBytes += dsiz;
281                  op->obin = bin0;
282                  for (bincnt = 1; bincnt < mp->nbins; bincnt++) {
283 <                        if (!modndx | (modndx > binndx))
283 >                        if (!modndx || (binndx > 0) &  (modndx > binndx))
284                                  sprintf(fnbuf, outspec, bin0+bincnt, modn);
285                          else
286                                  sprintf(fnbuf, outspec, modn, bin0+bincnt);
# Line 262 | Line 299 | RcontribSimulManager::AddModifier(const char *modn, co
299                          op->rowBytes += dsiz;
300                  }
301          } else                          // else send all results to this channel
302 <                op->rowBytes += bincnt*dsiz;
302 >                op->rowBytes += mp->nbins*dsiz;
303          return true;
304   }
305  
# Line 283 | Line 320 | RcontribSimulManager::AddModFile(const char *modfn, co
320          }
321          char            mod[MAXSTR];
322          while (fgetword(mod, sizeof(mod), fp))
323 <                if (!AddModifier(mod, outspec, prms, binval, bincnt))
323 >                if (!AddModifier(mod, outspec, prms, binval, bincnt)) {
324 >                        fclose(fp);
325                          return false;
326 +                }
327          fclose(fp);
328          return true;
329   }
330  
331 + // call-back to check if modifier has been loaded
332 + static int
333 + checkModExists(const LUENT *lp, void *p)
334 + {
335 +        OBJECT  mod = modifier(lp->key);
336 +
337 +        if ((mod != OVOID) & (mod < nsceneobjs))
338 +                return 1;
339 +
340 +        sprintf(errmsg, "tracked modifier '%s' not found in main scene", lp->key);
341 +        error(WARNING, errmsg);
342 +        return 0;
343 + }
344 +
345   // Prepare output channels and return # completed rows
346   int
347   RcontribSimulManager::PrepOutput()
348   {
349          if (!outList || !RtraceSimulManager::Ready()) {
350 <                error(INTERNAL, "PrepOutput() called before octree & modifiers assigned");
350 >                error(INTERNAL, "PrepOutput() called before octree & modifiers set");
351                  return -1;
352          }
353 +        if (!cdsF) {
354 +                error(INTERNAL, "missing RdataShare constructor call (cdsF)");
355 +                return -1;
356 +        }
357 +        if (lu_doall(&modLUT, checkModExists, NULL) < 0)
358 +                return -1;
359 +
360 +        outList->nRows = yres * (xres + !xres); // all outputs have same #rows
361          int     remWarnings = 20;
362          for (RcontribOutput *op = outList; op; op = op->next) {
363                  if (op->rData) {
364                          error(INTERNAL, "output channel already open in PrepOutput()");
365                          return -1;
366                  }
367 <                op->nRows = yres * (xres + !xres);
367 >                op->nRows = outList->nRows;
368                  op->rData = (*cdsF)(op->ofname, outOp,
369                                          GetHeadLen()+1024 + op->nRows*op->rowBytes);
370                  freeqstr(op->ofname); op->ofname = NULL;
# Line 313 | Line 374 | RcontribSimulManager::PrepOutput()
374                                  return -1;
375                          if (rd >= op->nRows) {
376                                  if (remWarnings >= 0) {
377 <                                        sprintf(errmsg, "recovered output '%s' already done",
377 >                                        sprintf(errmsg, "recovered output '%s' is complete",
378                                                          op->GetName());
379 <                                        error(WARNING, remWarnings ? errmsg : "etc...");
319 <                                        remWarnings--;
379 >                                        error(WARNING, --remWarnings ? errmsg : "etc...");
380                                  }
381                                  rd = op->nRows;
382                          }
# Line 358 | Line 418 | RcontribOutput::NewHeader(const RcontribSimulManager *
418          strcpy(hdr+begData, ROWZEROSTR);
419          rowCountPos = begData+LNROWSTR;
420          begData += sizeof(ROWZEROSTR)-1;
421 <        if (!xres | (rowBytes > esiz)) {
421 >        if (!rcp->xres | (rowBytes > esiz)) {
422                  sprintf(hdr+begData, "NCOLS=%d\n", int(rowBytes/esiz));
423                  begData += strlen(hdr+begData);
424          }
# Line 396 | Line 456 | RcontribOutput::NewHeader(const RcontribSimulManager *
456                          hdr[begData++] = ' ';
457          hdr[begData++] = '\n';          // EOL for data format
458          hdr[begData++] = '\n';          // end of nominal header
459 <        if ((xres > 0) & (rowBytes == esiz)) {  // tack on resolution string?
460 <                sprintf(hdr+begData, PIXSTDFMT, yres, xres);
459 >        if ((rcp->xres > 0) & (rowBytes == esiz)) {     // tack on resolution string?
460 >                sprintf(hdr+begData, PIXSTDFMT, rcp->yres, rcp->xres);
461                  begData += strlen(hdr+begData);
462          }
463          return rData->ReleaseMemory(hdr, RDSwrite);
# Line 443 | Line 503 | RcontribOutput::CheckHeader(const RcontribSimulManager
503                  return -1;
504          }
505                                                  // check format
506 <        if (!(cp = findArgs(hdr, FMTSTR, begData)) || strcmp(cp, formstr(etyp))) {
506 >        if (!(cp = findArgs(hdr, FMTSTR, begData)) ||
507 >                                strncmp(cp, formstr(etyp), strlen(formstr(etyp)))) {
508                  sprintf(errmsg, "expected %s%s in '%s'", FMTSTR, formstr(etyp), GetName());
509                  error(USER, errmsg);
510                  return -1;
511          }
512                                                  // check #columns
513          if (((cp = findArgs(hdr, "NCOLS=", begData)) && atoi(cp)*esiz != rowBytes) ||
514 <                        !xres | (rowBytes > esiz)) {
514 >                        !rcp->xres | (rowBytes > esiz)) {
515                  sprintf(errmsg, "expected NCOLS=%d in '%s'",
516                                  int(rowBytes/esiz), GetName());
517                  error(USER, errmsg);
# Line 465 | Line 526 | RcontribOutput::CheckHeader(const RcontribSimulManager
526          rowCountPos = cp - hdr;
527          int     rlast = atoi(cp);
528          begData++;                              // advance past closing EOL
529 <        if ((xres > 0) & (rowBytes == esiz)) {  // check/skip resolution string?
529 >        if ((rcp->xres > 0) & (rowBytes == esiz)) {     // check/skip resolution string?
530                  char    rbuf[64];
531 <                sprintf(rbuf, PIXSTDFMT, yres, xres);
531 >                sprintf(rbuf, PIXSTDFMT, rcp->yres, rcp->xres);
532                  int     rlen = strlen(rbuf);
533                  if (strncmp(rbuf, hdr+begData, rlen)) {
534                          sprintf(errmsg, "bad resolution string in '%s'", GetName());
# Line 632 | Line 693 | RcontribSimulManager::GetChild(bool forceWait)
693                                  FD_ISSET(kid[n].w, &writeset) |
694                                  FD_ISSET(kid[n].w, &errset)) {
695                                                  // update output row counts
696 <                        UpdateRowsDone(kidRow[n]);
696 >                        if (!FD_ISSET(kid[n].w, &errset))
697 >                                UpdateRowsDone(kidRow[n]);
698                          kidRow[n] = -1;         // flag it available
699                          pn = n;
700                  }
# Line 716 | Line 778 | RcontribSimulManager::StartKids(int n2go)
778                                  close(kid[nkids].w);
779                          free(kid); free(kidRow);
780                          kid = NULL; kidRow = NULL;
719                        rowsDone.NewBitMap(0);
781                          RunChild();             // should never return
782                          _exit(1);
783                  }
# Line 765 | Line 826 | RcontribSimulManager::SetThreadCount(int nt)
826                  return 0;
827          }
828          if (nt < 0)
829 <                return nkids;
829 >                return NThreads();
830          if (!nt) nt = GetNCores();
831          int     status = 0;
832          if (nt == 1)
# Line 778 | Line 839 | RcontribSimulManager::SetThreadCount(int nt)
839                  sprintf(errmsg, "non-zero (%d) status from child", status);
840                  error(WARNING, errmsg);
841          }
842 <        return nkids;
842 >        return NThreads();
843   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines