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

Comparing ray/src/rt/RpictSimulManager.cpp (file contents):
Revision 2.7 by greg, Thu Aug 22 00:44:02 2024 UTC vs.
Revision 2.11 by greg, Tue Aug 27 18:50:01 2024 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
9   *  Created by Greg Ward on 07/11/2024.
10   */
11  
12 + #define DEBUG   1       // XXX temporary!
13 +
14   #include <ctype.h>
15   #include "platform.h"
16   #include "RpictSimulManager.h"
# Line 196 | Line 198 | RpictSimulManager::SetTile(const int ti[2])
198   bool
199   RpictSimulManager::ComputePixel(int x, int y)
200   {
201 <        static const SCOLOR     scBlack = {0};
201 >        DCHECK(doneMap.OffBitMap(x,y),
202 >                        CONSISTENCY, "illegal pixel index in ComputPixel()");
203          int     i;
204          FVECT   rodir[2];
205          double  hpos = (x+pixjitter())/TWidth();
206          double  vpos = (y+pixjitter())/THeight();
207          double  dlim = viewray(rodir[0], rodir[1], &tvw, hpos, vpos);
208          if (dlim < -FTINY) {    // off view?
209 <                pacc.SetPixel(x, y, scBlack);
209 >                pacc.SetPixel(x, y, scblack);
210                  doneMap.Set(x, y);
211                  return true;
212          }
# Line 233 | Line 236 | RpictSimulManager::ComputePixel(int x, int y)
236  
237   // Check if neighbor differences are below pixel sampling threshold
238   bool
239 < RpictSimulManager::BelowSampThresh(int x, int y, const int noff[4][2]) const
239 > RpictSimulManager::BelowSampThresh(const int x, const int y, const int noff[4][2]) const
240   {
241          SCOLOR  pval[4];
242          float   dist[4];
243          int     i, j;
244  
245          for (i = 4; i--; ) {            // get pixels from tile store
246 <                int     px = x + noff[i][0];
247 <                int     py = y + noff[i][1];
246 >                const int       px = x + noff[i][0];
247 >                const int       py = y + noff[i][1];
248                  if (!doneMap.Check(px, py) ||
249                                  !pacc.GetPixel(px, py, pval[i], &dist[i]))
250                          return false;
251          }
252 <        const bool      spectr = (pacc.NC() > 3);
253 <        for (i = 4; --i; )              // do pairwise comparisons
254 <            for (j = i; j--; ) {
255 <                if (pacc.DepthType() &&
253 <                                (dist[i] - dist[j] > maxdiff*dist[j]) |
252 >                                        // do pairwise comparisons
253 >        for (i = (pacc.DepthType() != RDTnone)*4; --i > 0; )
254 >            for (j = i; j--; )
255 >                if ((dist[i] - dist[j] > maxdiff*dist[j]) |
256                                  (dist[j] - dist[i] > maxdiff*dist[i]))
257                          return false;
258 <                if (spectr ? sbigsdiff(pval[i], pval[j], maxdiff) :
259 <                                bigdiff(pval[i], pval[j], maxdiff))
258 >        if (pacc.NC() > 3) {
259 >            for (i = 4; --i; )
260 >                for (j = i; j--; )
261 >                    if (sbigsdiff(pval[i], pval[j], maxdiff))
262                          return false;
263 <            }
264 <        return true;                    // linear interpolation OK
263 >        } else {
264 >            for (i = 4; --i; )
265 >                for (j = i; j--; )
266 >                    if (bigdiff(pval[i], pval[j], maxdiff))
267 >                        return false;
268 >        }
269 >        return true;
270   }
271  
272   // Fill an interior square patch with interpolated values
# Line 268 | Line 277 | RpictSimulManager::FillSquare(const int x, const int y
277          float   dist[4];
278          int     i, j;
279                                          // assumes 4 corners are valid!
280 <        for (i = 4; i--; )
280 >        for (i = 4; i--; ) {
281 >                DCHECK(!doneMap.Check(x+noff[i][0], y+noff[i][1]),
282 >                        CONSISTENCY, "inclusion of bad pixel in FillSquare()");
283                  pacc.GetPixel(x+noff[i][0], y+noff[i][1], pval[i], &dist[i]);
284 <
284 >        }
285          i = abs(noff[1][0]-noff[0][0]);
286          j = abs(noff[1][1]-noff[0][1]); // i==j for diamond fill
287          const int       slen =  (i > j) ? i : j;
# Line 328 | Line 339 | RpictSimulManager::FillSquare(const int x, const int y
339  
340   // helper function to set up quincunx sampling
341   static void
342 < SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int spc, const bool odd)
342 > SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int spc, bool odd, int x0, int y)
343   {
344 <        for (int y = 0; y < bmp2->Height(); y += spc>>1)
334 <            for (int x = (odd^(y&1))*(spc>>1); x < bmp2->Width(); x += spc)
335 <                bmp2->Set(x, y);
336 <                                        // order neighbors CCW
337 <        if (odd) {
344 >        if (odd) {                      // order neighbors CCW
345                  noff[0][0] = spc>>1; noff[0][1] = 0;
346                  noff[1][0] = 0; noff[1][1] = spc>>1;
347                  noff[2][0] = -(spc>>1); noff[2][1] = 0;
# Line 345 | Line 352 | SetQuincunx(ABitMap2 *bmp2, int noff[4][2], const int
352                  noff[2][0] = -(spc>>1); noff[2][1] = -(spc>>1);
353                  noff[3][0] = spc>>1; noff[3][1] = -(spc>>1);
354          }
355 +        int     nsteps;                 // non-negative range
356 +        if (x0 < -(spc>>1)) {
357 +                nsteps = (spc-1 - x0 - (spc>>1))/spc;
358 +                x0 += nsteps*spc;
359 +        }
360 +        if (y < 0) {                    // get past y==0
361 +                nsteps = ((spc>>1)-1 - y)/(spc>>1);
362 +                y += nsteps*(spc>>1);
363 +                odd ^= nsteps&1;
364 +        }
365 +        while (y < bmp2->Height()) {
366 +            for (int x = x0 + odd*(spc>>1); x < bmp2->Width(); x += spc)
367 +                bmp2->Set(x, y);
368 +            y += spc>>1;
369 +            odd = !odd;
370 +        }
371   }
372  
373   // Render (or finish rendering) current tile
374   bool
375 < RpictSimulManager::RenderRect()
375 > RpictSimulManager::RenderRect(const int x0, const int y0)
376   {
377          if (!tvw.type || !Ready()) {
378                  error(INTERNAL, "need octree and view for RenderRect()");
# Line 359 | Line 382 | RpictSimulManager::RenderRect()
382          int             sp2 = ceil(log2((TWidth()>THeight() ? TWidth() : THeight()) - 1.));
383          int             layer = 0;
384          int             x, y;
362 // fprintf(stderr, "Rendering %dx%d tile with psample=%d, maxdiff=%.3f ...\n",
363 // TWidth(), THeight(), psample, maxdiff);
385          while (sp2 > 0) {
386                  ABitMap2        sampMap(TWidth(), THeight());
387                  int             noff[4][2];
388                  if ((prCB != NULL) & (barPix == NULL))
389                          (*prCB)(100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height());
390 <                SetQuincunx(&sampMap, noff, 1<<sp2, layer&1);
390 >                SetQuincunx(&sampMap, noff, 1<<sp2, layer&1, x0, y0);
391                  sampMap -= doneSamples; // avoid resampling pixels
392                  // Are we into adaptive sampling realm?
393                  if (noff[0][0]*noff[0][0] + noff[0][1]*noff[0][1] < psample*psample) {
# Line 380 | Line 401 | RpictSimulManager::RenderRect()
401                          const ABitMap2  origSampMap = sampMap;
402                          for (x = 4; x--; ) {
403                                  ABitMap2        stamp = origSampMap;
404 <                                stamp.Shift(noff[x][0], noff[x][1]);
404 >                                stamp.Shift(noff[x][0] + noff[(x+1)&3][0],
405 >                                                noff[x][1] + noff[(x+1)&3][1]);
406                                  sampMap |= stamp;
407                          }               // ...but don't resample what's done
408                          sampMap -= doneSamples;
409                                          // interpolate smooth regions
410                          fillMap -= sampMap;
411 +                        fillMap -= doneSamples;
412                          for (x = y = 0; fillMap.Find(&x, &y); x++)
413                                  FillSquare(x, y, noff);
414                          doneSamples |= doneMap;
# Line 394 | Line 417 | RpictSimulManager::RenderRect()
417                          if (!ComputePixel(x, y))
418                                  return false;
419                  doneSamples |= sampMap; // samples now done or at least queued
397 // fprintf(stderr, "Sampled %ld pixels at (sp2,layer)=(%d,%d)\n",
398 // (long)sampMap.SumTotal(), sp2, layer);
399 // fprintf(stderr, "\t%ld pixels (%.3f%%) completed (+%ld in process)\n",
400 // (long)doneMap.SumTotal(), 100.*doneMap.SumTotal()/doneMap.Width()/doneMap.Height(),
401 // (long)(doneSamples.SumTotal()-doneMap.SumTotal()));
420                  sp2 -= layer++ & 1;     // next denser sampling
421          }
422          if (FlushQueue() < 0)           // make sure we got everyone
423                  return false;
424          x = y = 0;
425          if (doneMap.Find(&x, &y, false)) {
426 <                sprintf(errmsg, "missed %ld tile pixels, e.g. (%d,%d)",
427 <                                (long)doneMap.Width()*doneMap.Height() -
428 <                                        doneMap.SumTotal(), x, y);
426 >                sprintf(errmsg, "missed %.4f%% of pixels in rectangle\n",
427 >                                100. - 100.*doneMap.SumTotal() /
428 >                                        doneMap.Width() / doneMap.Height());
429                  error(WARNING, errmsg);
430          }
431          if ((prCB != NULL) & (barPix == NULL))
# Line 433 | Line 451 | RpictSimulManager::RenderTile(COLORV *rp, int ystride,
451                  pacc.SetColorSpace(RDTxyz);
452          else if (prims)
453                  pacc.SetColorSpace(RDTrgb, prims);
454 <                
454 >
455          return SetTile(tile) && RenderRect();
456   }
457  
# Line 537 | Line 555 | RpictSimulManager::LowerBar(int v, int ytop)
555                          sizeof(COLORV)*NC*TWidth()*(THeight()-v));
556          memmove(barDepth, barDepth + TWidth()*v,
557                          sizeof(float)*TWidth()*(THeight()-v));
558 <        if (ytop < THeight()) {                 // mark what we won't do as finished
558 >        if (ytop < THeight())                   // mark what we won't do as finished
559                  doneMap.ClearRect(0, 0, TWidth(), THeight()-ytop, true);
542                memset(barPix, 0, sizeof(COLORV)*NC*TWidth()*(THeight()-ytop));
543                memset(barDepth, 0, sizeof(float)*TWidth()*(THeight()-ytop));
544        }
560          return true;
561   }
562  
# Line 564 | Line 579 | RpictSimulManager::RenderBelow(int ytop, const int vst
579                          cropview(&ptvw, 0., double(ytop-THeight())/GetHeight(),
580                                                  1., double(ytop)/GetHeight()))
581                  ptvw.type = 0;
582 <                                                // set up spectral sampling
583 <        if (setspectrsamp(CNDX, WLPART) <= 0) {
582 >                                                // update spectral sampling
583 >        int     rv = setspectrsamp(CNDX, WLPART);
584 >        if (rv < 0) {
585                  error(USER, "unsupported spectral sampling");
586                  return false;
587          }
588 +        if (!rv & (RDTcolorT(dt) != RDTscolor) & (RDTcolorT(dt) != RDTscolr))
589 +                error(WARNING, "spectral range incompatible with color output");
590          COLORV **       parr = NULL;            // set up tiny source drawing
591          float **        zarr = NULL;
592          if (!ptvw.type && directvis && dblur <= FTINY) {
# Line 583 | Line 601 | RpictSimulManager::RenderBelow(int ytop, const int vst
601          }
602          int             lastOut = ytop;         // render down frame
603          while (ytop > 0) {
586 // fprintf(stderr, "At y=%d, source drawing %s...\n", ytop, parr ? "ON" : "OFF");
604                  if (prCB)
605                          (*prCB)(100.*(GetHeight()-ytop)/GetHeight());
606 <                if (!RenderRect())              // render this bar
606 >                if (!RenderRect(0, THeight()-ytop))     // render this bar
607                          return false;
608                  int     nlines = lastOut - ytop + THeight();
609                  if (nlines > ytop)
# Line 652 | Line 669 | RpictSimulManager::NewOutput(FILE *pdfp[2], const char
669   {
670          pdfp[0] = pdfp[1] = NULL;
671          if (!RDTcolorT(dt))
672 <                error(INTERNAL, "botched color output type in NewOutput()");
672 >                error(INTERNAL, "missing color output type in NewOutput()");
673          if (NCSAMP == 3) {
674                  if (RDTcolorT(dt) == RDTscolr)
675                          dt = RDTnewCT(dt, prims==xyzprims ? RDTxyze : RDTrgbe);
# Line 674 | Line 691 | RpictSimulManager::NewOutput(FILE *pdfp[2], const char
691                          sprintf(errmsg, "cannot open picture file '%s'", pfname);
692                          error(SYSTEM, errmsg);
693                  }
694 <                return RDTnone;                 // expected in parallel sequence
694 >                return RDTnone;                 // may be expected in sequence run
695          }
696          if (fd == 1)
697                  pdfp[0] = stdout;
# Line 729 | Line 746 | RpictSimulManager::NewOutput(FILE *pdfp[2], const char
746                  fputendian(pdfp[0]);
747                  fputformat("float", pdfp[0]);
748                  break;
749 <        default:;
749 >        default:;       // pro forma - caught this above
750          }
751 <        fputc('\n', pdfp[0]);                   // flush picture header + resolution
751 >        fputc('\n', pdfp[0]);                   // flush picture header
752          if (fflush(pdfp[0]) == EOF) {
753                  sprintf(errmsg, "cannot write header to picture '%s'", pfname);
754                  error(SYSTEM, errmsg);
# Line 791 | Line 808 | RpictSimulManager::RenderFrame(const char *pfname, Ren
808          if (RDTdepthT(dt) == RDTdshort)
809                  fprtresolu(GetWidth(), GetHeight(), pdfp[1]);
810  
811 <        const int       bheight = (psample > 1) ? int(2*psample+.99) : 4;
812 <        const int       vstep =  bheight >> (psample > 1);
811 >        const int       bheight = (psample > 1) ? int(8*psample+.99) : 16;
812 >        const int       vstep = bheight >> (psample > 1);
813  
814          NewBar(bheight);                        // render frame if we can
815          if (!RenderBelow(GetHeight(), vstep, pdfp[0], dt, pdfp[1])) {
# Line 1154 | Line 1171 | RpictSimulManager::ResumeFrame(const char *pfname, con
1171                  fclose(pdfp[0]); fclose(pdfp[1]);
1172                  return RDTnone;
1173          }
1174 <        int     bheight = (psample > 1) ? int(2*psample+.99) : 4;
1174 >        int     bheight = (psample > 1) ? int(8*psample+.99) : 16;
1175          if (bheight > GetHeight()-doneScans)
1176                  bheight = GetHeight()-doneScans;
1177          int     vstep =  bheight >> (psample > 1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines