23 |
|
#include "pmapdiag.h" |
24 |
|
#include "rcontrib.h" |
25 |
|
#include "otypes.h" |
26 |
+ |
#include "otspecial.h" |
27 |
|
#if NIX |
28 |
|
#include <sys/mman.h> |
29 |
< |
#include <sys/wait.h> |
29 |
> |
#include <sys/wait.h> |
30 |
|
#endif |
31 |
|
|
32 |
|
|
61 |
|
|
62 |
|
if (primRay) { |
63 |
|
FVECT dvec; |
64 |
< |
|
64 |
> |
|
65 |
> |
#ifdef PMAP_PRIMARYDIR |
66 |
|
/* Reverse incident direction to point to light source */ |
67 |
|
dvec [0] = -primRay -> rdir [0]; |
68 |
|
dvec [1] = -primRay -> rdir [1]; |
69 |
|
dvec [2] = -primRay -> rdir [2]; |
70 |
|
pmap -> lastPrimary.dir = encodedir(dvec); |
71 |
+ |
#endif |
72 |
|
#ifdef PMAP_PRIMARYPOS |
73 |
|
VCOPY(pmap -> lastPrimary.pos, primRay -> rop); |
74 |
|
#endif |
173 |
|
|
174 |
|
|
175 |
|
|
176 |
+ |
|
177 |
+ |
|
178 |
+ |
|
179 |
|
void distribPhotonContrib (PhotonMap* pm, unsigned numProc) |
180 |
|
{ |
181 |
|
EmissionMap emap; |
231 |
|
if (!pm -> distribTarget) |
232 |
|
error(INTERNAL, "no photons to distribute in distribPhotonContrib"); |
233 |
|
|
234 |
< |
/* Get photon ports if specified */ |
235 |
< |
if (ambincl == 1) |
230 |
< |
getPhotonPorts(); |
234 |
> |
/* Get photon ports from modifier list */ |
235 |
> |
getPhotonPorts(photonPortList); |
236 |
|
|
237 |
|
/* Get photon sensor modifiers */ |
238 |
|
getPhotonSensors(photonSensorList); |
361 |
|
|
362 |
|
/* Seed RNGs from PID for decorellated photon distribution */ |
363 |
|
pmapSeed(randSeed + proc, partState); |
364 |
< |
pmapSeed(randSeed + proc, emitState); |
365 |
< |
pmapSeed(randSeed + proc, cntState); |
366 |
< |
pmapSeed(randSeed + proc, mediumState); |
367 |
< |
pmapSeed(randSeed + proc, scatterState); |
368 |
< |
pmapSeed(randSeed + proc, rouletteState); |
364 |
> |
pmapSeed(randSeed + (proc + 1) % numProc, emitState); |
365 |
> |
pmapSeed(randSeed + (proc + 2) % numProc, cntState); |
366 |
> |
pmapSeed(randSeed + (proc + 3) % numProc, mediumState); |
367 |
> |
pmapSeed(randSeed + (proc + 4) % numProc, scatterState); |
368 |
> |
pmapSeed(randSeed + (proc + 5) % numProc, rouletteState); |
369 |
> |
|
370 |
> |
#ifdef PMAP_SIGUSR |
371 |
> |
double partNumEmit; |
372 |
> |
unsigned long partEmitCnt; |
373 |
> |
double srcPhotonFlux, avgPhotonFlux; |
374 |
> |
unsigned portCnt, passCnt, prePassCnt; |
375 |
> |
float srcPreDistrib; |
376 |
> |
double srcNumEmit; /* # to emit from source */ |
377 |
> |
unsigned long srcNumDistrib; /* # stored */ |
378 |
> |
|
379 |
> |
void sigUsrDiags() |
380 |
> |
/* Loop diags via SIGUSR1 */ |
381 |
> |
{ |
382 |
> |
sprintf(errmsg, |
383 |
> |
"********************* Proc %d Diags *********************\n" |
384 |
> |
"srcIdx = %d (%s)\nportCnt = %d (%s)\npassCnt = %d\n" |
385 |
> |
"srcFlux = %f\nsrcPhotonFlux = %f\navgPhotonFlux = %f\n" |
386 |
> |
"partNumEmit = %f\npartEmitCnt = %lu\n\n", |
387 |
> |
proc, srcIdx, findmaterial(source [srcIdx].so) -> oname, |
388 |
> |
portCnt, photonPorts [portCnt].so -> oname, |
389 |
> |
passCnt, srcFlux [srcIdx], srcPhotonFlux, avgPhotonFlux, |
390 |
> |
partNumEmit, partEmitCnt); |
391 |
> |
eputs(errmsg); |
392 |
> |
fflush(stderr); |
393 |
> |
} |
394 |
> |
#endif |
395 |
|
|
396 |
+ |
#ifdef PMAP_SIGUSR |
397 |
+ |
signal(SIGUSR1, sigUsrDiags); |
398 |
+ |
#endif |
399 |
+ |
|
400 |
+ |
#ifdef DEBUG_PMAP |
401 |
+ |
/* Output child process PID after random delay to prevent corrupted |
402 |
+ |
* console output due to race condition */ |
403 |
+ |
usleep(1e6 * pmapRandom(rouletteState)); |
404 |
+ |
fprintf(stderr, "Proc %d: PID = %d " |
405 |
+ |
"(waiting 10 sec to attach debugger...)\n", |
406 |
+ |
proc, getpid()); |
407 |
+ |
/* Allow time for debugger to attach to child process */ |
408 |
+ |
sleep(10); |
409 |
+ |
#endif |
410 |
+ |
|
411 |
|
/* ============================================================= |
412 |
|
* 2-PASS PHOTON DISTRIBUTION |
413 |
|
* Pass 1 (pre): emit fraction of target photon count |
414 |
|
* Pass 2 (main): based on outcome of pass 1, estimate remaining |
415 |
|
* number of photons to emit to approximate target |
416 |
|
* count |
417 |
< |
* ============================================================= */ |
417 |
> |
* ============================================================= */ |
418 |
|
for (srcIdx = 0; srcIdx < nsources; srcIdx++) { |
419 |
+ |
#ifndef PMAP_SIGUSR |
420 |
|
unsigned portCnt, passCnt = 0, prePassCnt = 0; |
421 |
|
float srcPreDistrib = preDistrib; |
422 |
|
double srcNumEmit = 0; /* # to emit from source */ |
423 |
|
unsigned long srcNumDistrib = pm -> numPhotons; /* # stored */ |
424 |
+ |
#else |
425 |
+ |
passCnt = prePassCnt = 0; |
426 |
+ |
srcPreDistrib = preDistrib; |
427 |
+ |
srcNumEmit = 0; /* # to emit from source */ |
428 |
+ |
srcNumDistrib = pm -> numPhotons; /* # stored */ |
429 |
+ |
#endif |
430 |
|
|
431 |
|
if (srcFlux [srcIdx] < FTINY) |
432 |
|
continue; |
434 |
|
while (passCnt < 2) { |
435 |
|
if (!passCnt) { |
436 |
|
/* INIT PASS 1 */ |
437 |
< |
if (++prePassCnt > maxPreDistrib && !proc) { |
437 |
> |
if (++prePassCnt > maxPreDistrib) { |
438 |
|
/* Warn if no photons contributed after sufficient |
439 |
|
* iterations; only output from subprocess 0 to reduce |
440 |
|
* console clutter */ |
441 |
< |
sprintf(errmsg, |
442 |
< |
"source %s: too many prepasses, skipped", |
443 |
< |
source [srcIdx].so -> oname); |
444 |
< |
error(WARNING, errmsg); |
441 |
> |
if (!proc) { |
442 |
> |
sprintf(errmsg, |
443 |
> |
"source %s: too many prepasses, skipped", |
444 |
> |
source [srcIdx].so -> oname); |
445 |
> |
error(WARNING, errmsg); |
446 |
> |
} |
447 |
> |
|
448 |
|
break; |
449 |
|
} |
450 |
|
|
453 |
|
} |
454 |
|
else { |
455 |
|
/* INIT PASS 2 */ |
456 |
+ |
#ifndef PMAP_SIGUSR |
457 |
|
double srcPhotonFlux, avgPhotonFlux; |
458 |
+ |
#endif |
459 |
|
|
460 |
|
/* Based on the outcome of the predistribution we can now |
461 |
|
* figure out how many more photons we have to emit from |
477 |
|
srcPhotonFlux = srcFlux [srcIdx] / srcNumEmit; |
478 |
|
avgPhotonFlux = photonFluxSum / (srcIdx + 1); |
479 |
|
|
480 |
< |
if (avgPhotonFlux > 0 && |
480 |
> |
if (avgPhotonFlux > FTINY && |
481 |
|
srcPhotonFlux / avgPhotonFlux < FTINY) { |
482 |
|
/* Skip source if its photon flux is grossly below the |
483 |
|
* running average, indicating negligible contributions |
484 |
|
* at the expense of excessive distribution time; only |
485 |
|
* output from subproc 0 to reduce console clutter */ |
486 |
< |
sprintf(errmsg, |
487 |
< |
"source %s: itsy bitsy photon flux, skipped", |
488 |
< |
source [srcIdx].so -> oname); |
489 |
< |
error(WARNING, errmsg); |
490 |
< |
srcNumEmit = 0; |
486 |
> |
if (!proc) { |
487 |
> |
sprintf(errmsg, |
488 |
> |
"source %s: itsy bitsy photon flux, skipped", |
489 |
> |
source [srcIdx].so -> oname); |
490 |
> |
error(WARNING, errmsg); |
491 |
> |
} |
492 |
> |
|
493 |
> |
srcNumEmit = 0; /* Or just break??? */ |
494 |
|
} |
495 |
|
|
496 |
|
/* Update sum of photon flux per light source */ |
531 |
|
|
532 |
|
for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions; |
533 |
|
emap.partitionCnt++) { |
534 |
+ |
#ifndef PMAP_SIGUSR |
535 |
|
double partNumEmit; |
536 |
|
unsigned long partEmitCnt; |
537 |
+ |
#endif |
538 |
|
|
539 |
|
/* Get photon origin within current source partishunn |
540 |
|
* and build emission map */ |
631 |
|
pm -> numPhotons); |
632 |
|
eputs(errmsg); |
633 |
|
fflush(stderr); |
634 |
+ |
#endif |
635 |
+ |
|
636 |
+ |
#ifdef PMAP_SIGUSR |
637 |
+ |
signal(SIGUSR1, SIG_DFL); |
638 |
|
#endif |
639 |
|
|
640 |
|
#if NIX |