| 25 |
|
|
| 26 |
|
extern char RCCONTEXT[]; // global rcontrib context |
| 27 |
|
|
| 28 |
– |
extern int contrib; // computing contributions? |
| 29 |
– |
|
| 30 |
– |
extern int xres, yres; // global resolution settings |
| 31 |
– |
|
| 28 |
|
class RcontribSimulManager; // need forward decl |
| 29 |
|
|
| 30 |
|
/// Shared data object for record output (includes header; may be write-only) |
| 66 |
|
} |
| 67 |
|
/// Update output row count |
| 68 |
|
bool SetRowsDone(int r) { |
| 69 |
< |
if (!rData | (0 >= r) | (r > nRows)) return false; |
| 69 |
> |
if (!rData | (0 > r) | (r > nRows)) return false; |
| 70 |
|
char * rbuf = (char *)rData->GetMemory(rowCountPos, 17, 0); |
| 71 |
|
sprintf(rbuf, "%-16d", r); |
| 72 |
|
rbuf[16] = '\n'; // replaces nul byte |
| 108 |
|
|
| 109 |
|
typedef double DCOLORV; // color accumulator type |
| 110 |
|
|
| 115 |
– |
/// Modifier channel for recording contributions (no constructor/destructor) |
| 116 |
– |
struct RcontribMod; |
| 117 |
– |
|
| 118 |
– |
/// Allocate rcontrib accumulator |
| 119 |
– |
extern RcontribMod * NewRcMod(const char *prms = NULL, const char *binexpr = NULL, int ncbins = 1); |
| 111 |
|
/// Free an RcontribMod |
| 112 |
|
extern lut_free_t FreeRcMod; |
| 113 |
|
|
| 116 |
|
* |
| 117 |
|
* 1) Call LoadOctree(), then alter the header as desired |
| 118 |
|
* 2) Set number of spectral samples (NCSAMP) and call SetDataFormat() |
| 119 |
< |
* 3) Call AddModifier() and AddModFile() to indicate tracked modifiers |
| 120 |
< |
* 4) Set outOp and cdsF according to desired output/recovery |
| 121 |
< |
* 5) Call PrepOutput() to open output channels |
| 122 |
< |
* 6) Call SetThreadCount() to fork children if desired |
| 123 |
< |
* 7) Set accum to the number of ray samples per record |
| 124 |
< |
* 8) Call ComputeRecord() with accum ray samples |
| 125 |
< |
* 9) Continue until GetRowMax() records have been sent |
| 126 |
< |
* 10) Call Cleanup() |
| 119 |
> |
* 3) Set xres and yres to desired dimensions (xres>0 for picture output) |
| 120 |
> |
* 4) Call AddModifier() and AddModFile() to indicate tracked modifiers |
| 121 |
> |
* 5) Set outOp and cdsF according to desired output/recovery |
| 122 |
> |
* 6) Set desired computation flags via SetFlag() |
| 123 |
> |
* 7) Call PrepOutput() to open output channels |
| 124 |
> |
* 8) Call SetThreadCount() to fork children if desired |
| 125 |
> |
* 9) Set accum to the number of ray samples per record |
| 126 |
> |
* 10) Call ComputeRecord() with accum ray samples |
| 127 |
> |
* 11) Continue until GetRowMax() records have been sent |
| 128 |
> |
* 12) Call Cleanup() |
| 129 |
|
* |
| 130 |
|
* The order of some of these calls may be changed. Technically, the octree |
| 131 |
|
* may be loaded anytime before PrepOutput() is called. Also, SetThreadCount() |
| 132 |
< |
* may be called anytime after PrepOutput() and interleaved with |
| 132 |
> |
* may be called anytime *after* PrepOutput(), and may be interleaved with |
| 133 |
|
* calls to ComputeRecord(). The accum setting may be changed at any time. |
| 134 |
|
* Finally, it is possible to restart the output using ResetRow(), and |
| 135 |
|
* a zero argument will rewind to the beginning, whence all records |
| 136 |
|
* may be recalculated. The previous output rows are not zeroed or deleted, |
| 137 |
|
* but are overwritten as the calculation proceeds from the new starting point. |
| 138 |
|
* However, the output file(s) will indicate in the NROWS= line in the header |
| 139 |
< |
* that only the newly calculated rows are present. |
| 139 |
> |
* that only the newly calculated rows are present. If you wish to start over |
| 140 |
> |
* with a different set of modifiers or outputs, call ClearModifiers() instead, |
| 141 |
> |
* which keeps the current octree in memory. This call also returns to single |
| 142 |
> |
* process mode if any children were running. |
| 143 |
|
* |
| 144 |
|
* It is not possible to write to standard output, but the output |
| 145 |
|
* model is quite flexible thanks to the RdataShare polymorphic class. |
| 162 |
|
extern RcreateDataShareF defDataShare; |
| 163 |
|
|
| 164 |
|
/// Modifiable ray-tracing flags for rcontrib |
| 165 |
< |
#define RCmask (RTlimDist|RTimmIrrad) |
| 165 |
> |
#define RCcontrib (RTmask+1) // compute contributions? (r.t. coefficients) |
| 166 |
> |
#define RCmask (RTlimDist|RTimmIrrad|RCcontrib) |
| 167 |
|
|
| 168 |
|
/// rcontrib-like simulation manager (at most one such object) |
| 169 |
|
class RcontribSimulManager : protected RtraceSimulManager { |
| 187 |
|
public: |
| 188 |
|
RCOutputOp outOp; // output operation |
| 189 |
|
RcreateDataShareF * cdsF; // data share creator |
| 190 |
+ |
int xres, yres; // output (picture) size |
| 191 |
|
uint32 accum; // # rays to accumulate per record |
| 192 |
|
RcontribSimulManager(const char *octn = NULL) |
| 193 |
|
: RtraceSimulManager(NULL, NULL, octn) { |
| 202 |
|
modLUT.freek = efree; |
| 203 |
|
modLUT.freed = FreeRcMod; |
| 204 |
|
kid = NULL; kidRow = NULL; nkids = 0; |
| 207 |
– |
rtFlags = RTtraceSources; |
| 208 |
– |
SetTraceCall(&RctCall, this); |
| 205 |
|
outOp = RCOnew; |
| 206 |
|
cdsF = &defDataShare; |
| 207 |
+ |
xres = yres = 0; |
| 208 |
|
accum = 1; |
| 209 |
+ |
if (octname) { |
| 210 |
+ |
SetTraceCall(&RctCall, this); |
| 211 |
+ |
rtFlags |= RTtraceSources; |
| 212 |
+ |
UpdateMode(); |
| 213 |
+ |
} |
| 214 |
|
} |
| 215 |
|
~RcontribSimulManager() { |
| 216 |
< |
Cleanup(); |
| 216 |
> |
if (nkids >= 0) ClearModifiers(); |
| 217 |
|
} |
| 218 |
|
/// Check modifiable ray-tracing computation flag(s) |
| 219 |
|
bool HasFlag(int fl) const { |
| 228 |
|
} |
| 229 |
|
/// Load octree and prepare renderer |
| 230 |
|
bool LoadOctree(const char *octn) { |
| 231 |
< |
return RtraceSimulManager::LoadOctree(octn); |
| 231 |
> |
if (octname) Cleanup(false); |
| 232 |
> |
if (!RtraceSimulManager::LoadOctree(octn)) |
| 233 |
> |
return false; |
| 234 |
> |
SetTraceCall(&RctCall, this); |
| 235 |
> |
rtFlags |= RTtraceSources; |
| 236 |
> |
return UpdateMode(); |
| 237 |
|
} |
| 238 |
|
/// Prepare header from previous input (or clear) |
| 239 |
|
bool NewHeader(const char *inspec=NULL) { |
| 311 |
|
return rowsDone.Length(); |
| 312 |
|
return nDone; |
| 313 |
|
} |
| 307 |
– |
/// Rewind calculation (previous results unchanged) |
| 308 |
– |
bool ResetRow(int r); |
| 314 |
|
/// Add a ray/bundle to compute next record (n=accum) |
| 315 |
|
int ComputeRecord(const FVECT orig_direc[]); |
| 316 |
|
/// Finish pending rays if multi-processing |
| 320 |
|
; |
| 321 |
|
return true; |
| 322 |
|
} |
| 323 |
< |
/// Close octree, free data, return status |
| 324 |
< |
int Cleanup(bool everything = false) { |
| 323 |
> |
/// Rewind calculation (previous results unchanged) |
| 324 |
> |
bool ResetRow(int r); |
| 325 |
> |
/// Clear the modifiers and close all outputs |
| 326 |
> |
void ClearModifiers() { |
| 327 |
|
if (rowsDone.Length()) { |
| 328 |
|
SetThreadCount(1); |
| 322 |
– |
cow_doneshare(); |
| 329 |
|
rowsDone.NewBitMap(0); |
| 330 |
+ |
rInPos = 0; |
| 331 |
|
} |
| 332 |
|
lu_done(&modLUT); |
| 333 |
|
delete outList; outList = NULL; |
| 334 |
|
nChan = 0; |
| 335 |
+ |
} |
| 336 |
+ |
/// Close octree, free data, return status |
| 337 |
+ |
int Cleanup(bool everything = false) { |
| 338 |
+ |
ClearModifiers(); |
| 339 |
+ |
cow_doneshare(); |
| 340 |
+ |
if (everything) { |
| 341 |
+ |
dtyp = 'f'; |
| 342 |
+ |
outOp = RCOnew; |
| 343 |
+ |
cdsF = &defDataShare; |
| 344 |
+ |
xres = yres = 0; |
| 345 |
+ |
accum = 1; |
| 346 |
+ |
rtFlags &= ~RCmask; |
| 347 |
+ |
} |
| 348 |
|
return RtraceSimulManager::Cleanup(everything); |
| 349 |
|
} |
| 350 |
|
}; |
| 351 |
+ |
|
| 352 |
+ |
extern const char * formstr(int f); // string from format |
| 353 |
|
|
| 354 |
|
#endif /* RcontribSimulManager_h */ |