| 1 |
+ |
#ifndef lint |
| 2 |
+ |
static const char RCSid[] = "$Id$"; |
| 3 |
+ |
#endif |
| 4 |
|
/* |
| 5 |
|
================================================================== |
| 6 |
|
Photon map main module |
| 7 |
|
|
| 8 |
|
Roland Schregle (roland.schregle@{hslu.ch, gmail.com}) |
| 9 |
|
(c) Fraunhofer Institute for Solar Energy Systems, |
| 10 |
< |
Lucerne University of Applied Sciences & Arts |
| 10 |
> |
(c) Lucerne University of Applied Sciences and Arts, |
| 11 |
> |
supported by the Swiss National Science Foundation (SNSF, #147053) |
| 12 |
|
================================================================== |
| 13 |
|
|
| 10 |
– |
$Id$ |
| 14 |
|
*/ |
| 15 |
|
|
| 16 |
|
|
| 23 |
|
#include "pmapbias.h" |
| 24 |
|
#include "pmapdiag.h" |
| 25 |
|
#include "otypes.h" |
| 23 |
– |
#include <signal.h> |
| 26 |
|
#include <time.h> |
| 27 |
|
#include <sys/stat.h> |
| 28 |
|
|
| 67 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 68 |
|
if (setPmapParam(&pm, parm + t)) { |
| 69 |
|
/* Check if photon map newer than octree */ |
| 70 |
< |
if (!stat(pm -> fileName, &pmstat) && !stat(octname, &octstat) && |
| 70 |
> |
if (pm -> fileName && octname && |
| 71 |
> |
!stat(pm -> fileName, &pmstat) && !stat(octname, &octstat) && |
| 72 |
|
octstat.st_mtime > pmstat.st_mtime) { |
| 73 |
|
sprintf(errmsg, "photon map in file %s may be stale", |
| 74 |
|
pm -> fileName); |
| 103 |
|
|
| 104 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) { |
| 105 |
|
if (pmaps [t]) |
| 106 |
< |
savePhotonMap(pmaps [t], pmaps [t] -> fileName, t, argc, argv); |
| 106 |
> |
savePhotonMap(pmaps [t], pmaps [t] -> fileName, argc, argv); |
| 107 |
|
} |
| 108 |
|
} |
| 109 |
|
|
| 208 |
|
OBJREC* mat; |
| 209 |
|
|
| 210 |
|
if (ray -> rlvl > photonMaxBounce) { |
| 211 |
+ |
#ifdef PMAP_RUNAWAY_WARN |
| 212 |
|
error(WARNING, "runaway photon!"); |
| 213 |
+ |
#endif |
| 214 |
|
return; |
| 215 |
|
} |
| 216 |
< |
|
| 216 |
> |
|
| 217 |
|
if (colorAvg(ray -> cext) > FTINY && !photonParticipate(ray)) |
| 218 |
|
return; |
| 219 |
|
|
| 269 |
|
|
| 270 |
|
/* Record start time, baby */ |
| 271 |
|
repStartTime = time(NULL); |
| 272 |
< |
signal(SIGCONT, pmapPreCompReport); |
| 272 |
> |
#ifdef SIGCONT |
| 273 |
> |
signal(SIGCONT, pmapPreCompReport); |
| 274 |
> |
#endif |
| 275 |
|
repProgress = 0; |
| 276 |
< |
bcopy(pmap -> heap, nuHeap, nuHeapSize * sizeof(Photon)); |
| 276 |
> |
memcpy(nuHeap, pmap -> heap, nuHeapSize * sizeof(Photon)); |
| 277 |
|
|
| 278 |
|
for (i = 0, p = nuHeap; i < nuHeapSize; i++, p++) { |
| 279 |
|
ray.ro = NULL; |
| 292 |
|
|
| 293 |
|
if (photonRepTime > 0 && time(NULL) >= repLastTime + photonRepTime) |
| 294 |
|
pmapPreCompReport(); |
| 295 |
< |
#ifndef BSD |
| 296 |
< |
else signal(SIGCONT, pmapPreCompReport); |
| 297 |
< |
#endif |
| 295 |
> |
#ifdef SIGCONT |
| 296 |
> |
else signal(SIGCONT, pmapPreCompReport); |
| 297 |
> |
#endif |
| 298 |
|
} |
| 299 |
|
|
| 300 |
< |
signal(SIGCONT, SIG_DFL); |
| 300 |
> |
#ifdef SIGCONT |
| 301 |
> |
signal(SIGCONT, SIG_DFL); |
| 302 |
> |
#endif |
| 303 |
|
|
| 304 |
|
/* Replace & rebuild heap */ |
| 305 |
|
free(pmap -> heap); |
| 326 |
|
double totalFlux = 0; |
| 327 |
|
PhotonMap *pm; |
| 328 |
|
|
| 329 |
< |
for (t = 0; t < NUM_PMAP_TYPES && !photonMaps [t]; t++); |
| 329 |
> |
for (t = 0; t < NUM_PMAP_TYPES && !pmaps [t]; t++); |
| 330 |
|
if (t >= NUM_PMAP_TYPES) |
| 331 |
|
error(USER, "no photon maps defined"); |
| 332 |
|
|
| 344 |
|
|
| 345 |
|
/* Initialise all defined photon maps */ |
| 346 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 347 |
< |
initPhotonMap(photonMaps [t], t); |
| 347 |
> |
initPhotonMap(pmaps [t], t); |
| 348 |
|
|
| 349 |
|
initPhotonEmissionFuncs(); |
| 350 |
|
initPhotonScatterFuncs(); |
| 410 |
|
|
| 411 |
|
/* Record start time and enable progress report signal handler */ |
| 412 |
|
repStartTime = time(NULL); |
| 413 |
< |
signal(SIGCONT, pmapDistribReport); |
| 413 |
> |
#ifdef SIGCONT |
| 414 |
> |
signal(SIGCONT, pmapDistribReport); |
| 415 |
> |
#endif |
| 416 |
|
repProgress = prePassCnt = 0; |
| 417 |
|
|
| 418 |
|
if (photonRepTime) |
| 436 |
|
sprintf(errmsg, "too many prepasses"); |
| 437 |
|
|
| 438 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 439 |
< |
if (photonMaps [t] && !photonMaps [t] -> heapEnd) { |
| 439 |
> |
if (pmaps [t] && !pmaps [t] -> heapEnd) { |
| 440 |
|
sprintf(errmsg2, ", no %s photons stored", pmapName [t]); |
| 441 |
|
strcat(errmsg, errmsg2); |
| 442 |
|
} |
| 449 |
|
numEmit = FHUGE; |
| 450 |
|
|
| 451 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 452 |
< |
if (photonMaps [t]) |
| 453 |
< |
numEmit = min(photonMaps [t] -> distribTarget, numEmit); |
| 452 |
> |
if (pmaps [t]) |
| 453 |
> |
numEmit = min(pmaps [t] -> distribTarget, numEmit); |
| 454 |
|
|
| 455 |
|
numEmit *= preDistrib; |
| 456 |
|
} |
| 471 |
|
* Since this biases the photon density, addPhoton() promotes the |
| 472 |
|
* flux of stored photons to compensate. */ |
| 473 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 474 |
< |
if ((pm = photonMaps [t])) { |
| 474 |
> |
if ((pm = pmaps [t])) { |
| 475 |
|
pm -> distribRatio = (double)pm -> distribTarget / |
| 476 |
|
pm -> heapEnd - 1; |
| 477 |
|
|
| 496 |
|
/* Normalise distribution ratios and calculate number of photons to |
| 497 |
|
* emit in main pass */ |
| 498 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 499 |
< |
if ((pm = photonMaps [t])) |
| 499 |
> |
if ((pm = pmaps [t])) |
| 500 |
|
pm -> distribRatio /= maxDistribRatio; |
| 501 |
|
|
| 502 |
|
if ((numEmit = repProgress * maxDistribRatio) < FTINY) |
| 511 |
|
for (srcIdx = 0; srcIdx < nsources; srcIdx++) { |
| 512 |
|
unsigned portCnt = 0; |
| 513 |
|
emap.src = source + srcIdx; |
| 514 |
< |
|
| 514 |
> |
|
| 515 |
|
do { |
| 516 |
|
emap.port = emap.src -> sflags & SDISTANT ? photonPorts + portCnt |
| 517 |
|
: NULL; |
| 572 |
|
if (photonRepTime > 0 && |
| 573 |
|
time(NULL) >= repLastTime + photonRepTime) |
| 574 |
|
pmapDistribReport(); |
| 575 |
< |
#ifndef BSD |
| 575 |
> |
#ifdef SIGCONT |
| 576 |
|
else signal(SIGCONT, pmapDistribReport); |
| 577 |
|
#endif |
| 578 |
|
} |
| 583 |
|
} |
| 584 |
|
|
| 585 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 586 |
< |
if (photonMaps [t] && !photonMaps [t] -> heapEnd) { |
| 586 |
> |
if (pmaps [t] && !pmaps [t] -> heapEnd) { |
| 587 |
|
/* Double preDistrib in case a photon map is empty and redo |
| 588 |
|
* pass 1 --> possibility of infinite loop for pathological |
| 589 |
|
* scenes (e.g. absorbing materials) */ |
| 602 |
|
/* =================================================================== |
| 603 |
|
* POST-DISTRIBUTION - Set photon flux and build kd-tree, etc. |
| 604 |
|
* =================================================================== */ |
| 605 |
< |
signal(SIGCONT, SIG_DFL); |
| 605 |
> |
#ifdef SIGCONT |
| 606 |
> |
signal(SIGCONT, SIG_DFL); |
| 607 |
> |
#endif |
| 608 |
|
free(emap.samples); |
| 609 |
|
|
| 610 |
|
/* Set photon flux (repProgress is total num emitted) */ |
| 611 |
|
totalFlux /= repProgress; |
| 612 |
|
|
| 613 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
| 614 |
< |
if (photonMaps [t]) { |
| 614 |
> |
if (pmaps [t]) { |
| 615 |
|
if (photonRepTime) { |
| 616 |
|
sprintf(errmsg, "\nBuilding %s photon map...\n", pmapName [t]); |
| 617 |
|
eputs(errmsg); |
| 618 |
|
fflush(stderr); |
| 619 |
|
} |
| 620 |
|
|
| 621 |
< |
balancePhotons(photonMaps [t], &totalFlux); |
| 621 |
> |
balancePhotons(pmaps [t], &totalFlux); |
| 622 |
|
} |
| 623 |
|
|
| 624 |
|
/* Precompute photon irradiance if necessary */ |