ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RpictSimulManager.h
Revision: 2.10
Committed: Thu Oct 10 21:02:52 2024 UTC (6 months, 3 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.9: +1 -2 lines
Log Message:
fix: Allow unsetting of source-ray tracing flag

File Contents

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