ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/RpictSimulManager.h
Revision: 2.8
Committed: Mon Sep 16 19:18:32 2024 UTC (7 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +7 -3 lines
Log Message:
feat: Added method to get a specific string from header

File Contents

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