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 |
|
|
14 |
|
$Id$ |
68 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
69 |
|
if (setPmapParam(&pm, parm + t)) { |
70 |
|
/* Check if photon map newer than octree */ |
71 |
< |
if (!stat(pm -> fileName, &pmstat) && !stat(octname, &octstat) && |
71 |
> |
if (pm -> fileName && octname && |
72 |
> |
!stat(pm -> fileName, &pmstat) && !stat(octname, &octstat) && |
73 |
|
octstat.st_mtime > pmstat.st_mtime) { |
74 |
|
sprintf(errmsg, "photon map in file %s may be stale", |
75 |
|
pm -> fileName); |
104 |
|
|
105 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) { |
106 |
|
if (pmaps [t]) |
107 |
< |
savePhotonMap(pmaps [t], pmaps [t] -> fileName, t, argc, argv); |
107 |
> |
savePhotonMap(pmaps [t], pmaps [t] -> fileName, argc, argv); |
108 |
|
} |
109 |
|
} |
110 |
|
|
209 |
|
OBJREC* mat; |
210 |
|
|
211 |
|
if (ray -> rlvl > photonMaxBounce) { |
212 |
+ |
#ifdef PMAP_RUNAWAY_WARN |
213 |
|
error(WARNING, "runaway photon!"); |
214 |
+ |
#endif |
215 |
|
return; |
216 |
|
} |
217 |
< |
|
217 |
> |
|
218 |
|
if (colorAvg(ray -> cext) > FTINY && !photonParticipate(ray)) |
219 |
|
return; |
220 |
|
|
270 |
|
|
271 |
|
/* Record start time, baby */ |
272 |
|
repStartTime = time(NULL); |
273 |
< |
signal(SIGCONT, pmapPreCompReport); |
273 |
> |
#ifdef SIGCONT |
274 |
> |
signal(SIGCONT, pmapPreCompReport); |
275 |
> |
#endif |
276 |
|
repProgress = 0; |
277 |
|
memcpy(nuHeap, pmap -> heap, nuHeapSize * sizeof(Photon)); |
278 |
|
|
293 |
|
|
294 |
|
if (photonRepTime > 0 && time(NULL) >= repLastTime + photonRepTime) |
295 |
|
pmapPreCompReport(); |
296 |
< |
#ifndef BSD |
297 |
< |
else signal(SIGCONT, pmapPreCompReport); |
298 |
< |
#endif |
296 |
> |
#ifdef SIGCONT |
297 |
> |
else signal(SIGCONT, pmapPreCompReport); |
298 |
> |
#endif |
299 |
|
} |
300 |
|
|
301 |
< |
signal(SIGCONT, SIG_DFL); |
301 |
> |
#ifdef SIGCONT |
302 |
> |
signal(SIGCONT, SIG_DFL); |
303 |
> |
#endif |
304 |
|
|
305 |
|
/* Replace & rebuild heap */ |
306 |
|
free(pmap -> heap); |
327 |
|
double totalFlux = 0; |
328 |
|
PhotonMap *pm; |
329 |
|
|
330 |
< |
for (t = 0; t < NUM_PMAP_TYPES && !photonMaps [t]; t++); |
330 |
> |
for (t = 0; t < NUM_PMAP_TYPES && !pmaps [t]; t++); |
331 |
|
if (t >= NUM_PMAP_TYPES) |
332 |
|
error(USER, "no photon maps defined"); |
333 |
|
|
345 |
|
|
346 |
|
/* Initialise all defined photon maps */ |
347 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
348 |
< |
initPhotonMap(photonMaps [t], t); |
348 |
> |
initPhotonMap(pmaps [t], t); |
349 |
|
|
350 |
|
initPhotonEmissionFuncs(); |
351 |
|
initPhotonScatterFuncs(); |
411 |
|
|
412 |
|
/* Record start time and enable progress report signal handler */ |
413 |
|
repStartTime = time(NULL); |
414 |
< |
signal(SIGCONT, pmapDistribReport); |
414 |
> |
#ifdef SIGCONT |
415 |
> |
signal(SIGCONT, pmapDistribReport); |
416 |
> |
#endif |
417 |
|
repProgress = prePassCnt = 0; |
418 |
|
|
419 |
|
if (photonRepTime) |
437 |
|
sprintf(errmsg, "too many prepasses"); |
438 |
|
|
439 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
440 |
< |
if (photonMaps [t] && !photonMaps [t] -> heapEnd) { |
440 |
> |
if (pmaps [t] && !pmaps [t] -> heapEnd) { |
441 |
|
sprintf(errmsg2, ", no %s photons stored", pmapName [t]); |
442 |
|
strcat(errmsg, errmsg2); |
443 |
|
} |
450 |
|
numEmit = FHUGE; |
451 |
|
|
452 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
453 |
< |
if (photonMaps [t]) |
454 |
< |
numEmit = min(photonMaps [t] -> distribTarget, numEmit); |
453 |
> |
if (pmaps [t]) |
454 |
> |
numEmit = min(pmaps [t] -> distribTarget, numEmit); |
455 |
|
|
456 |
|
numEmit *= preDistrib; |
457 |
|
} |
472 |
|
* Since this biases the photon density, addPhoton() promotes the |
473 |
|
* flux of stored photons to compensate. */ |
474 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
475 |
< |
if ((pm = photonMaps [t])) { |
475 |
> |
if ((pm = pmaps [t])) { |
476 |
|
pm -> distribRatio = (double)pm -> distribTarget / |
477 |
|
pm -> heapEnd - 1; |
478 |
|
|
497 |
|
/* Normalise distribution ratios and calculate number of photons to |
498 |
|
* emit in main pass */ |
499 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
500 |
< |
if ((pm = photonMaps [t])) |
500 |
> |
if ((pm = pmaps [t])) |
501 |
|
pm -> distribRatio /= maxDistribRatio; |
502 |
|
|
503 |
|
if ((numEmit = repProgress * maxDistribRatio) < FTINY) |
512 |
|
for (srcIdx = 0; srcIdx < nsources; srcIdx++) { |
513 |
|
unsigned portCnt = 0; |
514 |
|
emap.src = source + srcIdx; |
515 |
< |
|
515 |
> |
|
516 |
|
do { |
517 |
|
emap.port = emap.src -> sflags & SDISTANT ? photonPorts + portCnt |
518 |
|
: NULL; |
573 |
|
if (photonRepTime > 0 && |
574 |
|
time(NULL) >= repLastTime + photonRepTime) |
575 |
|
pmapDistribReport(); |
576 |
< |
#ifndef BSD |
576 |
> |
#ifdef SIGCONT |
577 |
|
else signal(SIGCONT, pmapDistribReport); |
578 |
|
#endif |
579 |
|
} |
584 |
|
} |
585 |
|
|
586 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
587 |
< |
if (photonMaps [t] && !photonMaps [t] -> heapEnd) { |
587 |
> |
if (pmaps [t] && !pmaps [t] -> heapEnd) { |
588 |
|
/* Double preDistrib in case a photon map is empty and redo |
589 |
|
* pass 1 --> possibility of infinite loop for pathological |
590 |
|
* scenes (e.g. absorbing materials) */ |
603 |
|
/* =================================================================== |
604 |
|
* POST-DISTRIBUTION - Set photon flux and build kd-tree, etc. |
605 |
|
* =================================================================== */ |
606 |
< |
signal(SIGCONT, SIG_DFL); |
606 |
> |
#ifdef SIGCONT |
607 |
> |
signal(SIGCONT, SIG_DFL); |
608 |
> |
#endif |
609 |
|
free(emap.samples); |
610 |
|
|
611 |
|
/* Set photon flux (repProgress is total num emitted) */ |
612 |
|
totalFlux /= repProgress; |
613 |
|
|
614 |
|
for (t = 0; t < NUM_PMAP_TYPES; t++) |
615 |
< |
if (photonMaps [t]) { |
615 |
> |
if (pmaps [t]) { |
616 |
|
if (photonRepTime) { |
617 |
|
sprintf(errmsg, "\nBuilding %s photon map...\n", pmapName [t]); |
618 |
|
eputs(errmsg); |
619 |
|
fflush(stderr); |
620 |
|
} |
621 |
|
|
622 |
< |
balancePhotons(photonMaps [t], &totalFlux); |
622 |
> |
balancePhotons(pmaps [t], &totalFlux); |
623 |
|
} |
624 |
|
|
625 |
|
/* Precompute photon irradiance if necessary */ |