ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RpictSimulManager.h
Revision: 2.2
Committed: Sun Aug 18 00:37:13 2024 UTC (8 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +27 -28 lines
Log Message:
fix(rxpict): Fixed fill algorithm for pixel sampling

File Contents

# User Rev Content
1 greg 2.2 /* RCSid $Id: RpictSimulManager.h,v 2.1 2024/08/14 20:05:23 greg Exp $ */
2 greg 2.1 /*
3     * RpictSimulManager.h
4     *
5     * Rpict simulation manager class declaration
6     *
7     * Created by Greg Ward on 07/11/2024.
8     */
9    
10     #ifndef RpictSimulManager_h
11     #define RpictSimulManager_h
12    
13     #include "RtraceSimulManager.h"
14     #include "view.h"
15     #include "depthcodec.h"
16     #include "abitmap.h"
17    
18     /// Data type flags for pixel access and output
19     enum RenderDataType {
20     RDTnone=0,
21     RDTscolor=0x1, RDTrgb=0x2, RDTxyz=0x3, RDTscolr=0x4, RDTrgbe=0x5, RDTxyze=0x6,
22     RDTcolorM=0x7,
23     RDTdfloat=0x8, RDTdshort=0x10,
24     RDTdepthM=0x18
25     };
26    
27     #define RDTcolorT(f) RenderDataType((f) & RDTcolorM)
28     #define RDTdepthT(f) RenderDataType((f) & RDTdepthM)
29     #define RDTcommonE(f) (RDTcolorT(f) >= RDTscolr)
30 greg 2.2 #define RDTnewCT(f,c) RenderDataType((f) & ~RDTcolorM | (c) & RDTcolorM)
31     #define RDTnewDT(f,d) RenderDataType((f) & ~RDTdepthM | (d) & RDTdepthM)
32 greg 2.1
33     /// Pixel accessor (read/write to caller's buffer with possible conversion)
34     class PixelAccess {
35     union {
36     COLORV * f;
37     COLRV * b;
38     } pbase; // pixel base pointer
39     union {
40     float * f;
41     short * s;
42     } dbase; // depth base pointer
43     long rowStride; // # values to next y position
44     int dtyp; // data type flags
45     RGBPRIMP primp; // color primaries if tristimulus
46 greg 2.2 const COLORV * CF3(int x, int y) const {
47     return pbase.f + (rowStride*y + x)*3;
48     }
49 greg 2.1 COLORV * CF3(int x, int y) {
50     return pbase.f + (rowStride*y + x)*3;
51     }
52 greg 2.2 const COLRV * CB3(int x, int y) const {
53     return pbase.b + (rowStride*y + x)*4;
54     }
55     COLRV * CB3(int x, int y) {
56     return pbase.b + (rowStride*y + x)*4;
57     }
58     const COLORV * SCF(int x, int y) const {
59     return pbase.f + (rowStride*y + x)*NCSAMP;
60 greg 2.1 }
61     COLORV * SCF(int x, int y) {
62     return pbase.f + (rowStride*y + x)*NCSAMP;
63     }
64 greg 2.2 const COLRV * SCB(int x, int y) const {
65     return pbase.b + (rowStride*y + x)*(NCSAMP+1);
66 greg 2.1 }
67     COLRV * SCB(int x, int y) {
68     return pbase.b + (rowStride*y + x)*(NCSAMP+1);
69     }
70     public:
71     double refDepth; // reference depth
72     PixelAccess() {
73     refDepth = 1.;
74     Init();
75     }
76     PixelAccess(COLORV *rp, int ystride, float *zp=NULL) {
77     refDepth = 1.;
78     Init(rp, ystride, zp);
79     }
80     PixelAccess(COLRV *bp, int ystride, float *zp=NULL) {
81     refDepth = 1.;
82     Init(bp, ystride, zp);
83     }
84     PixelAccess(COLRV *bp, int ystride, short *dp) {
85     refDepth = 1.;
86     Init(bp, ystride, dp);
87     }
88     void Init() {
89     pbase.f = NULL; dbase.f = NULL;
90     rowStride = 0;
91     primp = NULL;
92     dtyp = 0;
93     }
94     /// Initializers default to rendering color space
95     void Init(COLORV *rp, int ystride, float *zp=NULL) {
96     pbase.f = rp; dbase.f = zp;
97     rowStride = ystride;
98     if (NCSAMP > 3) {
99     dtyp = RDTscolor; primp = NULL;
100     } else {
101     dtyp = RDTrgb; primp = stdprims;
102     }
103     if (zp) dtyp |= RDTdfloat;
104     }
105     void Init(COLRV *bp, int ystride, float *zp=NULL) {
106     pbase.b = bp; dbase.f = zp;
107     rowStride = ystride;
108     if (NCSAMP > 3) {
109     dtyp = RDTscolr; primp = NULL;
110     } else {
111     dtyp = RDTrgbe; primp = stdprims;
112     }
113     if (zp) dtyp |= RDTdfloat;
114     }
115     void Init(COLRV *bp, int ystride, short *dp) {
116     pbase.b = bp; dbase.s = dp;
117     rowStride = ystride;
118     if (NCSAMP > 3) {
119     dtyp = RDTscolr; primp = NULL;
120     } else {
121     dtyp = RDTrgbe; primp = stdprims;
122     }
123     if (dp) dtyp |= RDTdshort;
124     }
125     /// Set color space after non-empty initialization
126     bool SetColorSpace(RenderDataType cs, RGBPRIMP pr=NULL);
127     /// Get color space
128     RenderDataType ColorSpace() const {
129     return RDTcolorT(dtyp);
130     }
131     /// Get color primaries (NULL if spectral)
132     RGBPRIMP Primaries() const {
133     return primp;
134     }
135     /// Number of represented color/spectral components
136     int NC() const {
137     switch (ColorSpace()) {
138     case RDTrgb: case RDTrgbe:
139     case RDTxyz: case RDTxyze:
140     return 3;
141     case RDTscolor: case RDTscolr:
142     return NCSAMP;
143     default:;
144     }
145     return 0;
146     }
147     /// Get depth type
148     RenderDataType DepthType() const {
149     return RDTdepthT(dtyp);
150     }
151     /// Get row stride
152     long GetRowStride() const {
153     return rowStride;
154     }
155     /// Assign a pixel value (& depth) from rendered ray value
156     bool SetPixel(int x, int y, const RAY *rp);
157     /// Assign pixel color (& depth) -- may re-represent either/both
158     bool SetPixel(int x, int y, const COLORV *pv, float z=0) {
159     if (NC() == 3) {
160     if (RDTcommonE(dtyp))
161     setcolr(CB3(x,y), pv[RED], pv[GRN], pv[BLU]);
162     else
163     copycolor(CF3(x,y), pv);
164     } else if (RDTcommonE(dtyp))
165     scolor_scolr(SCB(x,y), pv);
166     else
167     copyscolor(SCF(x,y), pv);
168     if (RDTdepthT(dtyp) == RDTdfloat)
169     dbase.f[rowStride*y + x] = z;
170     else if (RDTdepthT(dtyp) == RDTdshort)
171     dbase.s[rowStride*y + x] = depth2code(z, refDepth);
172     return true;
173     }
174     /// Retrieve pixel color (& depth) -- may convert either/both
175     bool GetPixel(int x, int y, COLORV *pv, float *zp=NULL) const {
176     if (NC() == 3) {
177     if (RDTcommonE(dtyp))
178 greg 2.2 colr_color(pv, CB3(x,y));
179 greg 2.1 else
180 greg 2.2 copycolor(pv, CF3(x,y));
181 greg 2.1 } else if (RDTcommonE(dtyp))
182 greg 2.2 scolr_scolor(pv, SCB(x,y));
183 greg 2.1 else
184 greg 2.2 copyscolor(pv, SCF(x,y));
185 greg 2.1 if (!zp) return true;
186     if (RDTdepthT(dtyp) == RDTdfloat)
187     *zp = dbase.f[rowStride*y + x];
188     else if (RDTdepthT(dtyp) == RDTdshort)
189     *zp = code2depth(dbase.s[rowStride*y + x], refDepth);
190     else
191     *zp = .0f;
192     return true;
193     }
194     /// Copy pixel from one location to another (no conversion)
195     bool CopyPixel(int dx, int dy, int sx, int sy) {
196     if ((dx==sx) & (dy==sy)) return true;
197     const int nc = NC();
198     if (nc == 3) {
199     if (RDTcommonE(dtyp))
200 greg 2.2 copycolr(CB3(dx,dy), CB3(sx,sy));
201 greg 2.1 else
202 greg 2.2 copycolor(CF3(dx,dy), CF3(sx,sy));
203 greg 2.1 } else if (RDTcommonE(dtyp))
204 greg 2.2 copyscolr(SCB(dx,dy), SCB(sx,sy));
205 greg 2.1 else
206 greg 2.2 copyscolor(SCF(dx,dy), SCF(sx,sy));
207 greg 2.1 switch (RDTdepthT(dtyp)) {
208     case RDTdfloat:
209     dbase.f[rowStride*dy + dx] =
210     dbase.f[rowStride*sy + sx];
211     break;
212     case RDTdshort:
213     dbase.s[rowStride*dy + dx] =
214     dbase.s[rowStride*sy + sx];
215     break;
216     default:;
217     }
218     return true;
219     }
220     };
221    
222     /// Call-back function for progress reporting
223     typedef void ProgReportCB(double pct);
224    
225     /// rpict-like simulation manager (at most one such object)
226     class RpictSimulManager : protected RtraceSimulManager {
227     static RayReportCall RtCall; // our callback for cooked rays
228     VIEW vw; // frame view
229     VIEW pvw; // previous view
230     int hvres[2]; // overall picture dimensions
231     int tgsize[2]; // tile grid size
232     int thvres[2]; // tile dimensions
233     VIEW tvw, ptvw; // this tile's view (& previous)
234     PixelAccess pacc; // pixel accessor
235     char dunit[32]; // depth with units (if any)
236     ABitMap2 doneMap; // which tile pixels are done
237     COLORV * barPix; // current render bar pixels
238     float * barDepth; // current render bar depths
239     bool SetTile(const int ti[2]);
240     bool RenderRect();
241     bool ComputePixel(int x, int y);
242     bool BelowSampThresh(int x, int y, const int noff[4][2]) const;
243 greg 2.2 void FillSquare(const int x, const int y, const int noff[4][2]);
244 greg 2.1 void NewBar(int ht = 0);
245     bool LowerBar(int v);
246     bool RenderBelow(int ytop, const int vstep, FILE *pfp,
247     const int dt, FILE *dfp=NULL);
248     public:
249     ProgReportCB * prCB; // progress report call-back
250     RGBPRIMP prims; // output primaries (NULL if spectral)
251     int frameNo; // frame number (0 if not sequence)
252     RpictSimulManager(const char *octn = NULL) :
253     RtraceSimulManager(RtCall, this, octn) {
254     tvw.type = vw.type = 0;
255     hvres[0] = hvres[1] = 0;
256     thvres[0] = thvres[1] = 0;
257     pacc.refDepth = 1.; dunit[0] = '1'; dunit[1] = '\0';
258     barPix = NULL; barDepth = NULL;
259     prCB = NULL;
260     prims = NULL;
261     frameNo = 0;
262     }
263     ~RpictSimulManager() {
264     NewBar();
265     }
266     /// Load octree and prepare renderer
267     bool LoadOctree(const char *octn) {
268     return RtraceSimulManager::LoadOctree(octn);
269     }
270     /// Prepare header from previous input (or clear)
271     bool NewHeader(const char *inspec=NULL) {
272     return RtraceSimulManager::NewHeader(inspec);
273     }
274     /// Add a string to header (adds newline if none)
275     bool AddHeader(const char *str) {
276     return RtraceSimulManager::AddHeader(str);
277     }
278     /// Append program line to header
279     bool AddHeader(int ac, char *av[]) {
280     return RtraceSimulManager::AddHeader(ac, av);
281     }
282     /// Get header lines if any
283     const char * GetHeader() const {
284     return RtraceSimulManager::GetHeader();
285     }
286     /// Set number of computation threads (0 => #cores)
287     int SetThreadCount(int nt = 0) {
288     return RtraceSimulManager::SetThreadCount(nt);
289     }
290     /// Check thread count (1 means no multi-threading)
291     int NThreads() const {
292     return RtraceSimulManager::NThreads();
293     }
294     /// How many threads are currently unoccupied?
295     int ThreadsAvailable() const {
296     return RtraceSimulManager::ThreadsAvailable();
297     }
298     /// Are we ready?
299     bool Ready() const {
300     return RtraceSimulManager::Ready();
301     }
302     /// Assign reference depth string (e.g., "2.5/meter")
303     bool SetReferenceDepth(const char *dstr) {
304     double dref = atof(dstr);
305     if (dref <= .0) return false;
306     strlcpy(dunit, dstr, sizeof(dunit));
307     pacc.refDepth = dref;
308     return true;
309     }
310     bool SetReferenceDepth(double dref, const char *unit=NULL) {
311     if (dref <= .0) return false;
312     if (unit) sprintf(dunit, "%g/%s", dref, unit);
313     else sprintf(dunit, "%g", dref);
314     pacc.refDepth = dref;
315     return true;
316     }
317     /// Return reference depth
318     double GetReferenceDepth(char *du=NULL) const {
319     if (du) strcpy(du, dunit);
320     return pacc.refDepth;
321     }
322     /// Set up rendering frame (call after octree loaded)
323     /// Overall dimensions may be adjusted for view,
324     /// optional pixel aspect ratio and tile grid
325     /// Increments frameNo if >0
326     bool NewFrame(const VIEW &v, int xydim[2], double *ap=NULL,
327     const int *tgrid=NULL);
328     /// Get current picture width
329     int GetWidth() const {
330     return hvres[0];
331     }
332     /// Get current picture height
333     int GetHeight() const {
334     return hvres[1];
335     }
336     /// Tile width
337     int TWidth() const {
338     return thvres[0];
339     }
340     /// Tile height
341     int THeight() const {
342     return thvres[1];
343     }
344     /// Render the specified tile in frame
345     /// Tile pixels are contiguous unless ystride != 0
346     /// Tiles numbered from lower-left at (0,0)
347     /// Pixel type influenced by this->prims assignment
348     bool RenderTile(COLORV *rp, int ystride=0, float *zp=NULL,
349     const int *tile=NULL);
350     /// Same but store as common-exponent COLR or SCOLR
351     bool RenderTile(COLRV *bp, int ystride=0, float *zp=NULL,
352     const int *tile=NULL);
353     /// Same but also use 16-bit encoded depth buffer
354     bool RenderTile(COLRV *bp, int ystride, short *dp,
355     const int *tile=NULL);
356     /// Render and write a frame to the named file
357     /// Include any header lines set prior to call
358     /// Picture file must not already exist
359 greg 2.2 /// Write pixels to stdout if !pfname
360     /// Write depth to a command if dfname[0]=='!'
361 greg 2.1 RenderDataType RenderFrame(const char *pfname,
362     RenderDataType dt=RDTrgbe,
363     const char *dfname=NULL);
364     /// Resume partially finished rendering
365     /// Picture file must exist with valid header
366     RenderDataType ResumeFrame(const char *pfname,
367     const char *dfname=NULL);
368     /// Close octree, free data, return status
369     int Cleanup(bool everything = false) {
370     NewBar();
371     tvw.type = vw.type = 0;
372     hvres[0] = hvres[1] = 0;
373     thvres[0] = thvres[1] = 0;
374     prims = NULL;
375     frameNo = 0;
376     return RtraceSimulManager::Cleanup(everything);
377     }
378     };
379    
380     #endif /* RpictSimulManager_h */