--- ray/src/rt/RpictSimulManager.cpp 2024/08/25 03:13:07 2.9 +++ ray/src/rt/RpictSimulManager.cpp 2025/01/10 19:09:12 2.13 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: RpictSimulManager.cpp,v 2.9 2024/08/25 03:13:07 greg Exp $"; +static const char RCSid[] = "$Id: RpictSimulManager.cpp,v 2.13 2025/01/10 19:09:12 greg Exp $"; #endif /* * RpictSimulManager.cpp @@ -105,8 +105,12 @@ RpictSimulManager::NewFrame(const VIEW &v, int xydim[2 if (!xydim) return false; if (!ap) ap = &pasp; - pvw = vw; // save previous view for motion blur - vw = v; + if (&v == &vw) { + pvw.type = 0; + } else { + pvw = vw; // save previous view for motion blur + vw = v; + } const char * verr = setview(&vw); if (verr) { error(WARNING, verr); @@ -236,31 +240,37 @@ RpictSimulManager::ComputePixel(int x, int y) // Check if neighbor differences are below pixel sampling threshold bool -RpictSimulManager::BelowSampThresh(int x, int y, const int noff[4][2]) const +RpictSimulManager::BelowSampThresh(const int x, const int y, const int noff[4][2]) const { SCOLOR pval[4]; float dist[4]; int i, j; for (i = 4; i--; ) { // get pixels from tile store - int px = x + noff[i][0]; - int py = y + noff[i][1]; + const int px = x + noff[i][0]; + const int py = y + noff[i][1]; if (!doneMap.Check(px, py) || !pacc.GetPixel(px, py, pval[i], &dist[i])) return false; } - const bool spectr = (pacc.NC() > 3); - for (i = 4; --i; ) // do pairwise comparisons - for (j = i; j--; ) { - if (pacc.DepthType() && - (dist[i] - dist[j] > maxdiff*dist[j]) | + // do pairwise comparisons + for (i = (pacc.DepthType() != RDTnone)*4; --i > 0; ) + for (j = i; j--; ) + if ((dist[i] - dist[j] > maxdiff*dist[j]) | (dist[j] - dist[i] > maxdiff*dist[i])) return false; - if (spectr ? sbigsdiff(pval[i], pval[j], maxdiff) : - bigdiff(pval[i], pval[j], maxdiff)) + if (pacc.NC() > 3) { + for (i = 4; --i; ) + for (j = i; j--; ) + if (sbigsdiff(pval[i], pval[j], maxdiff)) return false; - } - return true; // linear interpolation OK + } else { + for (i = 4; --i; ) + for (j = i; j--; ) + if (bigdiff(pval[i], pval[j], maxdiff)) + return false; + } + return true; } // Fill an interior square patch with interpolated values @@ -391,26 +401,28 @@ RpictSimulManager::RenderRect(const int x0, const int for (x = y = 0; sampMap.Find(&x, &y); x++) if (BelowSampThresh(x, y, noff)) sampMap.Reset(x, y); -#if 0 -XXX Need to fix directions for spreading!! // spread sampling to neighbors... const ABitMap2 origSampMap = sampMap; for (x = 4; x--; ) { ABitMap2 stamp = origSampMap; - stamp.Shift(noff[x][0], noff[x][1]); + stamp.Shift(noff[x][0] + noff[(x+1)&3][0], + noff[x][1] + noff[(x+1)&3][1]); sampMap |= stamp; } // ...but don't resample what's done sampMap -= doneSamples; -#endif // interpolate smooth regions fillMap -= sampMap; + fillMap -= doneSamples; for (x = y = 0; fillMap.Find(&x, &y); x++) FillSquare(x, y, noff); doneSamples |= doneMap; } // compute required ray samples for (x = y = 0; sampMap.Find(&x, &y); x++) - if (!ComputePixel(x, y)) + if (!ComputePixel(x, y)) { + sprintf(errmsg, "ComputePixel(%d,%d) failed", x, y); + error(WARNING, errmsg); return false; + } doneSamples |= sampMap; // samples now done or at least queued sp2 -= layer++ & 1; // next denser sampling } @@ -418,9 +430,9 @@ XXX Need to fix directions for spreading!! return false; x = y = 0; if (doneMap.Find(&x, &y, false)) { - sprintf(errmsg, "missed %ld tile pixels, e.g. (%d,%d)", - (long)doneMap.Width()*doneMap.Height() - - doneMap.SumTotal(), x, y); + sprintf(errmsg, "missed %.4f%% of pixels in rectangle\n", + 100. - 100.*doneMap.SumTotal() / + doneMap.Width() / doneMap.Height()); error(WARNING, errmsg); } if ((prCB != NULL) & (barPix == NULL)) @@ -447,12 +459,7 @@ RpictSimulManager::RenderTile(COLORV *rp, int ystride, else if (prims) pacc.SetColorSpace(RDTrgb, prims); - int x0=0, y0=0; - if (tile) { - x0 = -tile[0]*TWidth(); - y0 = -tile[1]*THeight(); - } - return SetTile(tile) && RenderRect(x0, y0); + return SetTile(tile) && RenderRect(); } // Same but store as common-exponent COLR or SCOLR @@ -469,12 +476,7 @@ RpictSimulManager::RenderTile(COLRV *bp, int ystride, else if (prims) pacc.SetColorSpace(RDTrgbe, prims); - int x0=0, y0=0; - if (tile) { - x0 = -tile[0]*TWidth(); - y0 = -tile[1]*THeight(); - } - return SetTile(tile) && RenderRect(x0, y0); + return SetTile(tile) && RenderRect(); } // Same but also use 16-bit encoded depth buffer @@ -491,12 +493,7 @@ RpictSimulManager::RenderTile(COLRV *bp, int ystride, else if (prims) pacc.SetColorSpace(RDTrgbe, prims); - int x0=0, y0=0; - if (tile) { - x0 = -tile[0]*TWidth(); - y0 = -tile[1]*THeight(); - } - return SetTile(tile) && RenderRect(x0, y0); + return SetTile(tile) && RenderRect(); } // Back to float color with 16-bit depth @@ -513,12 +510,7 @@ RpictSimulManager::RenderTile(COLORV *rp, int ystride, else if (prims) pacc.SetColorSpace(RDTrgb, prims); - int x0=0, y0=0; - if (tile) { - x0 = -tile[0]*TWidth(); - y0 = -tile[1]*THeight(); - } - return SetTile(tile) && RenderRect(x0, y0); + return SetTile(tile) && RenderRect(); } // Allocate a new render bar @@ -595,10 +587,13 @@ RpictSimulManager::RenderBelow(int ytop, const int vst 1., double(ytop)/GetHeight())) ptvw.type = 0; // update spectral sampling - if (setspectrsamp(CNDX, WLPART) <= 0) { + int rv = setspectrsamp(CNDX, WLPART); + if (rv < 0) { error(USER, "unsupported spectral sampling"); return false; } + if (!rv & (RDTcolorT(dt) != RDTscolor) & (RDTcolorT(dt) != RDTscolr)) + error(WARNING, "spectral range incompatible with color output"); COLORV ** parr = NULL; // set up tiny source drawing float ** zarr = NULL; if (!ptvw.type && directvis && dblur <= FTINY) { @@ -696,7 +691,7 @@ RpictSimulManager::NewOutput(FILE *pdfp[2], const char error(INTERNAL, "writing picture to a command not supported"); return RDTnone; } - fd = open(pfname, O_WRONLY|O_CREAT|O_EXCL, 0666); + fd = open(pfname, O_RDWR|O_CREAT|O_EXCL, 0666); } if (fd < 0) { if ((frameNo <= 0) | (errno != EEXIST)) { @@ -707,12 +702,12 @@ RpictSimulManager::NewOutput(FILE *pdfp[2], const char } if (fd == 1) pdfp[0] = stdout; - else if (!(pdfp[0] = fdopen(fd, "w"))) + else if (!(pdfp[0] = fdopen(fd, "w+"))) error(SYSTEM, "failure calling fdopen()"); SET_FILE_BINARY(pdfp[0]); // write picture header if ((pdfp[0] != stdout) | (frameNo <= 1)) { newheader("RADIANCE", pdfp[0]); - fputs(GetHeader(), pdfp[0]); + fputs(GetHeadStr(), pdfp[0]); } fputs(VIEWSTR, pdfp[0]); fprintview(&vw, pdfp[0]); fputc('\n', pdfp[0]); if (frameNo > 0) @@ -772,7 +767,7 @@ RpictSimulManager::NewOutput(FILE *pdfp[2], const char if (dfname[0] == '!') pdfp[1] = popen(dfname+1, "w"); else - pdfp[1] = fopen(dfname, "w"); + pdfp[1] = fopen(dfname, "w+"); if (!pdfp[1]) { sprintf(errmsg, "cannot open depth output '%s'", dfname); error(SYSTEM, errmsg); @@ -784,7 +779,7 @@ RpictSimulManager::NewOutput(FILE *pdfp[2], const char } if (RDTdepthT(dt) == RDTdshort) { // write header for 16-bit depth? newheader("RADIANCE", pdfp[1]); - fputs(GetHeader(), pdfp[1]); + fputs(GetHeadStr(), pdfp[1]); fputs(VIEWSTR, pdfp[1]); fprintview(&vw, pdfp[1]); fputc('\n', pdfp[1]); fputs(DEPTHSTR, pdfp[1]); fputs(dunit, pdfp[1]); fputc('\n', pdfp[1]); fputformat(DEPTH16FMT, pdfp[1]); @@ -820,14 +815,13 @@ RpictSimulManager::RenderFrame(const char *pfname, Ren if (RDTdepthT(dt) == RDTdshort) fprtresolu(GetWidth(), GetHeight(), pdfp[1]); - const int bheight = (psample > 1) ? int(4*psample+.99) : 8; + const int bheight = (psample > 1) ? int(8*psample+.99) : 16; const int vstep = bheight >> (psample > 1); NewBar(bheight); // render frame if we can if (!RenderBelow(GetHeight(), vstep, pdfp[0], dt, pdfp[1])) { fclose(pdfp[0]); if (pdfp[1]) (dfname[0] == '!') ? pclose(pdfp[1]) : fclose(pdfp[1]); - Cleanup(); return RDTnone; } NewBar(); // clean up and return @@ -1014,6 +1008,10 @@ RpictSimulManager::ReopenOutput(FILE *pdfp[2], const c pdfp[0] = NULL; return RDTnone; } + if (hinfo.gotview) { // header view overrides + pvw = vw; + vw = hinfo.vw; + } if (!dfname) // no depth file? return dt; @@ -1033,7 +1031,7 @@ RpictSimulManager::ReopenOutput(FILE *pdfp[2], const c } SET_FILE_BINARY(pdfp[1]); int n, len = strlen(HDRSTR); - char buf[32]; // sniff for 16-bit header + char buf[32]; // sniff for 16-bit header if (getbinary(buf, 1, len+1, pdfp[1]) < len+1) { sprintf(errmsg, "empty depth file '%s'", dfname); error(SYSTEM, errmsg); @@ -1043,12 +1041,12 @@ RpictSimulManager::ReopenOutput(FILE *pdfp[2], const c } for (n = 0; n < len; n++) if (buf[n] != HDRSTR[n]) - break; // not a Radiance header + break; // not a Radiance header rewind(pdfp[1]); if ((n < len) | !isprint(buf[len])) return RDTnewDT(dt, RDTdfloat); - HeaderInfo dinfo; // thinking it's 16-bit encoded + HeaderInfo dinfo; // thinking it's 16-bit encoded if (getheader(pdfp[1], head_check, &dinfo) < 0) sprintf(errmsg, "bad header in encoded depth file '%s'", dfname); @@ -1087,17 +1085,17 @@ RpictSimulManager::ResumeFrame(const char *pfname, con case RDTxyze: break; case RDTscolr: - bytesPer = hinfo.ncomp + 1; // XXX assumes no compression + bytesPer = NCSAMP + 1; // XXX assumes no compression break; case RDTrgb: case RDTxyz: bytesPer = sizeof(float)*3; break; case RDTscolor: - bytesPer = sizeof(float)*hinfo.ncomp; + bytesPer = sizeof(float)*NCSAMP; break; default: - sprintf(errmsg, "unknown format (%s) for '%s'", hinfo.fmt, pfname); + sprintf(errmsg, "unknown format for '%s'", pfname); error(USER, errmsg); fclose(pdfp[0]); if (pdfp[1]) fclose(pdfp[1]); @@ -1111,11 +1109,10 @@ RpictSimulManager::ResumeFrame(const char *pfname, con if (pdfp[1]) fclose(pdfp[1]); return RDTnone; } - vw.type = 0; // set up new (unreferenced) frame - frameNo = 0; + frameNo = 0; // set up unreferenced frame int hvdim[2] = {res.xr, res.yr}; double noAdj = 0; - if (!NewFrame(hinfo.vw, hvdim, &noAdj) || + if (!NewFrame(vw, hvdim, &noAdj) || (hvdim[0] != res.xr) | (hvdim[1] != res.yr)) { error(CONSISTENCY, "unexpected resolution change in ResumeFrame()"); fclose(pdfp[0]); @@ -1183,7 +1180,7 @@ RpictSimulManager::ResumeFrame(const char *pfname, con fclose(pdfp[0]); fclose(pdfp[1]); return RDTnone; } - int bheight = (psample > 1) ? int(4*psample+.99) : 8; + int bheight = (psample > 1) ? int(8*psample+.99) : 16; if (bheight > GetHeight()-doneScans) bheight = GetHeight()-doneScans; int vstep = bheight >> (psample > 1); @@ -1193,7 +1190,6 @@ RpictSimulManager::ResumeFrame(const char *pfname, con if (!RenderBelow(GetHeight()-doneScans, vstep, pdfp[0], dt, pdfp[1])) { fclose(pdfp[0]); if (pdfp[1]) fclose(pdfp[1]); - Cleanup(); return RDTnone; } NewBar(); // close up and return success