ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmap.c
(Generate patch)

Comparing ray/src/rt/pmap.c (file contents):
Revision 2.12 by greg, Mon Sep 26 20:19:30 2016 UTC vs.
Revision 2.18 by rschregle, Fri Feb 19 02:10:35 2021 UTC

# Line 2 | Line 2
2   static const char RCSid[] = "$Id$";
3   #endif
4  
5 +
6   /*
7     ======================================================================
8     Photon map main module
9  
10     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
11     (c) Fraunhofer Institute for Solar Energy Systems,
12 +       supported by the German Research Foundation
13 +       (DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme FARESYS")
14     (c) Lucerne University of Applied Sciences and Arts,
15 <       supported by the Swiss National Science Foundation (SNSF, #147053)
15 >       supported by the Swiss National Science Foundation
16 >       (SNSF #147053, "Daylight Redirecting Components")
17     ======================================================================
18    
19     $Id$
20   */
21  
22  
19
23   #include "pmap.h"
24   #include "pmapmat.h"
25   #include "pmapsrc.h"
# Line 25 | Line 28 | static const char RCSid[] = "$Id$";
28   #include "pmapbias.h"
29   #include "pmapdiag.h"
30   #include "otypes.h"
31 + #include "otspecial.h"
32   #include <time.h>
33 < #include <sys/stat.h>
34 < #include <sys/mman.h>
35 < #include <sys/wait.h>
33 > #if NIX
34 >   #include <sys/stat.h>
35 >   #include <sys/mman.h>
36 >   #include <sys/wait.h>
37 > #endif
38  
39  
34
40   void savePmaps (const PhotonMap **pmaps, int argc, char **argv)
41   {
42     unsigned t;
# Line 49 | Line 54 | static int photonParticipate (RAY *ray)
54     or 0 if absorbed and $*%&ed. Analogon to rayparticipate(). */
55   {
56     int i;
57 <   RREAL cosTheta, cosPhi, du, dv;
57 >   RREAL xi1, cosTheta, phi, du, dv;
58     const float cext = colorAvg(ray -> cext),
59 <               albedo = colorAvg(ray -> albedo);
59 >               albedo = colorAvg(ray -> albedo),
60 >               gecc = ray -> gecc, gecc2 = sqr(gecc);
61     FVECT u, v;
62     COLOR cvext;
63  
# Line 59 | Line 65 | static int photonParticipate (RAY *ray)
65     ray -> rmax = -log(pmapRandom(mediumState)) / cext;
66    
67     while (!localhit(ray, &thescene)) {
68 +      if (!incube(&thescene, ray -> rop)) {
69 +         /* Terminate photon if it has leaked from the scene */
70 + #ifdef DEBUG_PMAP
71 +         fprintf(stderr,
72 +                 "Volume photon leaked from scene at [%.3f %.3f %.3f]\n",
73 +                 ray -> rop [0], ray -> rop [1], ray -> rop [2]);
74 + #endif                
75 +         return 0;
76 +      }
77 +        
78        setcolor(cvext, exp(-ray -> rmax * ray -> cext [0]),
79                        exp(-ray -> rmax * ray -> cext [1]),
80                        exp(-ray -> rmax * ray -> cext [2]));
# Line 68 | Line 84 | static int photonParticipate (RAY *ray)
84        colorNorm(ray -> rcol);
85        VCOPY(ray -> rorg, ray -> rop);
86        
87 + #if 0
88        if (albedo > FTINY && ray -> rlvl > 0)
89 + #else
90 +      /* Store volume photons unconditionally in mist to also account for
91 +         direct inscattering from sources */
92 +      if (albedo > FTINY)
93 + #endif
94           /* Add to volume photon map */
95           newPhoton(volumePmap, ray);
96          
# Line 81 | Line 103 | static int photonParticipate (RAY *ray)
103        scalecolor(ray -> rcol, 1 / albedo);    
104        
105        /* Scatter photon */
106 <      cosTheta = ray -> gecc <= FTINY ? 2 * pmapRandom(scatterState) - 1
107 <                                      : 1 / (2 * ray -> gecc) *
108 <                                            (1 + ray -> gecc * ray -> gecc -
109 <                                               (1 - ray -> gecc * ray -> gecc) /
110 <                                               (1 - ray -> gecc + 2 * ray -> gecc *
111 <                                                  pmapRandom(scatterState)));
112 <                                                  
113 <      cosPhi = cos(2 * PI * pmapRandom(scatterState));
114 <      du = dv = sqrt(1 - cosTheta * cosTheta);   /* sin(theta) */
115 <      du *= cosPhi;
116 <      dv *= sqrt(1 - cosPhi * cosPhi);           /* sin(phi) */
106 >      xi1 = pmapRandom(scatterState);
107 >      cosTheta = ray -> gecc <= FTINY
108 >                    ? 2 * xi1 - 1
109 >                    : 0.5 / gecc *
110 >                      (1 + gecc2 - sqr((1 - gecc2) /
111 >                                       (1 + gecc * (2 * xi1 - 1))));
112 >
113 >      phi = 2 * PI * pmapRandom(scatterState);
114 >      du = dv = sqrt(1 - sqr(cosTheta));     /* sin(theta) */
115 >      du *= cos(phi);
116 >      dv *= sin(phi);
117        
118        /* Get axes u & v perpendicular to photon direction */
119        i = 0;
# Line 105 | Line 127 | static int photonParticipate (RAY *ray)
127        for (i = 0; i < 3; i++)
128           ray -> rdir [i] = du * u [i] + dv * v [i] +
129                             cosTheta * ray -> rdir [i];
130 +
131        ray -> rlvl++;
132        ray -> rmax = -log(pmapRandom(mediumState)) / cext;
133     }  
134 <    
134 >  
135 >   /* Passed through medium until intersecting local object */  
136     setcolor(cvext, exp(-ray -> rot * ray -> cext [0]),
137                     exp(-ray -> rot * ray -> cext [1]),
138                     exp(-ray -> rot * ray -> cext [2]));
139                    
140     /* Modify ray color and normalise */
141     multcolor(ray -> rcol, cvext);
142 <   colorNorm(ray -> rcol);
143 <  
120 <   /* Passed through medium */  
142 >   colorNorm(ray -> rcol);  
143 >
144     return 1;
145   }
146  
# Line 127 | Line 150 | void tracePhoton (RAY *ray)
150   /* Follow photon as it bounces around... */
151   {
152     long mod;
153 <   OBJREC* mat;
153 >   OBJREC *mat, *port = NULL;
154 >  
155 >   if (!ray -> parent) {
156 >      /* !!!  PHOTON PORT REJECTION SAMPLING HACK: get photon port for
157 >       * !!!  primary ray from ray -> ro, then reset the latter to NULL so
158 >       * !!!  as not to interfere with localhit() */
159 >      port = ray -> ro;
160 >      ray -> ro = NULL;
161 >   }
162  
163     if (ray -> rlvl > photonMaxBounce) {
164   #ifdef PMAP_RUNAWAY_WARN  
# Line 138 | Line 169 | void tracePhoton (RAY *ray)
169    
170     if (colorAvg(ray -> cext) > FTINY && !photonParticipate(ray))
171        return;
172 <      
172 >
173     if (localhit(ray, &thescene)) {
174        mod = ray -> ro -> omod;
175 <      
175 >
176 >      /* XXX: Is port -> omod != mod sufficient here? Probably not... */
177 >      if (
178 >         port && ray -> ro != port &&
179 >         findmaterial(port) != findmaterial(ray -> ro)
180 >      ) {
181 >         /* !!! PHOTON PORT REJECTION SAMPLING HACK !!!
182 >          * Terminate photon if emitted from port without intersecting it or
183 >          * its other associated surfaces or same material.
184 >          * This can happen when the port's partitions extend beyond its
185 >          * actual geometry, e.g.  with polygons.  Since the total flux
186 >          * relayed by the port is based on the (in this case) larger
187 >          * partition area, it is overestimated; terminating these photons
188 >          * constitutes rejection sampling and thereby compensates any bias
189 >          * incurred by the overestimated flux.  */
190 > #ifdef PMAP_PORTREJECT_WARN
191 >         sprintf(errmsg, "photon outside port %s", ray -> ro -> oname);
192 >         error(WARNING, errmsg);
193 > #endif        
194 >         return;
195 >      }
196 >
197        if ((ray -> clipset && inset(ray -> clipset, mod)) || mod == OVOID) {
198           /* Transfer ray if modifier is VOID or clipped within antimatta */
199           RAY tray;
# Line 173 | Line 225 | static void preComputeGlobal (PhotonMap *pmap)
225  
226     repComplete = numPreComp = finalGather * pmap -> numPhotons;
227    
228 <   if (photonRepTime) {
229 <      sprintf(errmsg, "Precomputing irradiance for %ld global photons...\n",
228 >   if (verbose) {
229 >      sprintf(errmsg,
230 >              "\nPrecomputing irradiance for %ld global photons\n",
231                numPreComp);
232        eputs(errmsg);
233 + #if NIX      
234        fflush(stderr);
235 + #endif      
236     }
237    
238     /* Copy photon map for precomputed photons */
# Line 204 | Line 259 | static void preComputeGlobal (PhotonMap *pmap)
259    
260     for (i = 0; i < numPreComp; i++) {
261        /* Get random photon from stratified distribution in source heap to
262 <       * avoid duplicates and clutering */
262 >       * avoid duplicates and clustering */
263        pIdx = firstPhoton(pmap) +
264               (unsigned long)((i + pmapRandom(pmap -> randState)) /
265                               finalGather);
# Line 242 | Line 297 | static void preComputeGlobal (PhotonMap *pmap)
297     deletePhotons(pmap);
298     memcpy(pmap, &nuPmap, sizeof(PhotonMap));
299    
300 <   if (photonRepTime) {
301 <      eputs("Rebuilding precomputed photon map...\n");
300 >   if (verbose) {
301 >      eputs("\nRebuilding precomputed photon map\n");
302 > #if NIX      
303        fflush(stderr);
304 + #endif      
305     }
306  
307     /* Rebuild underlying data structure, destroying heap */  
# Line 263 | Line 320 | typedef struct {
320   void distribPhotons (PhotonMap **pmaps, unsigned numProc)
321   {
322     EmissionMap    emap;
323 <   char           errmsg2 [128], shmFname [255];
323 >   char           errmsg2 [128], shmFname [PMAP_TMPFNLEN];
324     unsigned       t, srcIdx, proc;
325     double         totalFlux = 0;
326     int            shmFile, stat, pid;
# Line 295 | Line 352 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
352           initPhotonHeap(pmaps [t]);
353           /* Per-subprocess target count */
354           pmaps [t] -> distribTarget /= numProc;
355 +        
356 +         if (!pmaps [t] -> distribTarget)
357 +            error(INTERNAL, "no photons to distribute in distribPhotons");
358        }
359  
360     initPhotonEmissionFuncs();
361     initPhotonScatterFuncs();
362    
363 <   /* Get photon ports if specified */
364 <   if (ambincl == 1)
305 <      getPhotonPorts();
363 >   /* Get photon ports from modifier list */
364 >   getPhotonPorts(photonPortList);
365  
366     /* Get photon sensor modifiers */
367     getPhotonSensors(photonSensorList);
368    
369 + #if NIX
370     /* Set up shared mem for photon counters (zeroed by ftruncate) */
371 < #if 0  
312 <   snprintf(shmFname, 255, PMAP_SHMFNAME, getpid());
313 <   shmFile = shm_open(shmFname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
314 < #else
315 <   strcpy(shmFname, PMAP_SHMFNAME);
371 >   strcpy(shmFname, PMAP_TMPFNAME);
372     shmFile = mkstemp(shmFname);
317 #endif      
373  
374 <   if (shmFile < 0)
375 <      error(SYSTEM, "failed opening shared memory file in distribPhotons");
374 >   if (shmFile < 0 || ftruncate(shmFile, sizeof(*photonCnt)) < 0)
375 >      error(SYSTEM, "failed shared mem init in distribPhotons");
376  
322   if (ftruncate(shmFile, sizeof(*photonCnt)) < 0)
323      error(SYSTEM, "failed setting shared memory size in distribPhotons");
324
377     photonCnt = mmap(NULL, sizeof(*photonCnt), PROT_READ | PROT_WRITE,
378                      MAP_SHARED, shmFile, 0);
379                      
380     if (photonCnt == MAP_FAILED)
381 <      error(SYSTEM, "failed mapping shared memory in distribPhotons");
381 >      error(SYSTEM, "failed mapping shared memory in distribPhotons");
382 > #else
383 >   /* Allocate photon counters statically on Windoze */
384 >   if (!(photonCnt = malloc(sizeof(PhotonCnt))))
385 >      error(SYSTEM, "failed trivial malloc in distribPhotons");
386 >   photonCnt -> numEmitted = photonCnt -> numComplete = 0;      
387 > #endif /* NIX */
388  
389 <   if (photonRepTime)
390 <      eputs("\n");
389 >   if (verbose) {
390 >      sprintf(errmsg, "\nIntegrating flux from %d sources", nsources);
391 >      
392 >      if (photonPorts) {
393 >         sprintf(errmsg2, " via %d ports", numPhotonPorts);
394 >         strcat(errmsg, errmsg2);
395 >      }
396 >      
397 >      strcat(errmsg, "\n");
398 >      eputs(errmsg);
399 >   }  
400    
401     /* ===================================================================
402      * FLUX INTEGRATION - Get total photon flux from light sources
# Line 343 | Line 410 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
410                                                     : NULL;
411           photonPartition [emap.src -> so -> otype] (&emap);
412          
413 <         if (photonRepTime) {
414 <            sprintf(errmsg, "Integrating flux from source %s ",
413 >         if (verbose) {
414 >            sprintf(errmsg, "\tIntegrating flux from source %s ",
415                      source [srcIdx].so -> oname);
416 <                    
416 >
417              if (emap.port) {
418                 sprintf(errmsg2, "via port %s ",
419                         photonPorts [portCnt].so -> oname);
420                 strcat(errmsg, errmsg2);
421              }
422 <            
423 <            sprintf(errmsg2, "(%lu partitions)...\n", emap.numPartitions);
422 >
423 >            sprintf(errmsg2, "(%lu partitions)\n", emap.numPartitions);
424              strcat(errmsg, errmsg2);
425              eputs(errmsg);
426 + #if NIX            
427              fflush(stderr);
428 + #endif            
429           }
430          
431           for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions;
# Line 371 | Line 440 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
440  
441     if (totalFlux < FTINY)
442        error(USER, "zero flux from light sources");
443 +      
444 +   /* Record start time for progress reports */
445 +   repStartTime = time(NULL);
446  
447 +   if (verbose) {
448 +      sprintf(errmsg, "\nPhoton distribution @ %d procs\n", numProc);
449 +      eputs(errmsg);
450 +   }
451 +
452     /* MAIN LOOP */  
453     for (proc = 0; proc < numProc; proc++) {
454 + #if NIX          
455        if (!(pid = fork())) {
456 <         /* SUBPROCESS ENTERS HERE.
457 <            All opened and memory mapped files are inherited */
456 >         /* SUBPROCESS ENTERS HERE; open and mmapped files inherited */
457 > #else
458 >      if (1) {
459 >         /* No subprocess under Windoze */
460 > #endif
461 >         /* Local photon counters for this subprocess */
462           unsigned       passCnt = 0, prePassCnt = 0;
463           unsigned long  lastNumPhotons [NUM_PMAP_TYPES];
464           unsigned long  localNumEmitted = 0; /* Num photons emitted by this
# Line 384 | Line 466 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
466          
467           /* Seed RNGs from PID for decorellated photon distribution */
468           pmapSeed(randSeed + proc, partState);
469 <         pmapSeed(randSeed + proc, emitState);
470 <         pmapSeed(randSeed + proc, cntState);
471 <         pmapSeed(randSeed + proc, mediumState);
472 <         pmapSeed(randSeed + proc, scatterState);
473 <         pmapSeed(randSeed + proc, rouletteState);
474 <                  
469 >         pmapSeed(randSeed + (proc + 1) % numProc, emitState);
470 >         pmapSeed(randSeed + (proc + 2) % numProc, cntState);
471 >         pmapSeed(randSeed + (proc + 3) % numProc, mediumState);
472 >         pmapSeed(randSeed + (proc + 4) % numProc, scatterState);
473 >         pmapSeed(randSeed + (proc + 5) % numProc, rouletteState);
474 >              
475 > #ifdef DEBUG_PMAP          
476 >         /* Output child process PID after random delay to prevent corrupted
477 >          * console output due to race condition */
478 >         usleep(1e6 * pmapRandom(rouletteState));
479 >         fprintf(stderr, "Proc %d: PID = %d "
480 >                 "(waiting 10 sec to attach debugger...)\n",
481 >                 proc, getpid());
482 >         /* Allow time for debugger to attach to child process */
483 >         sleep(10);
484 > #endif            
485 >
486           for (t = 0; t < NUM_PMAP_TYPES; t++)
487              lastNumPhotons [t] = 0;
488              
# Line 409 | Line 502 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
502                  * iterations; make it clear to user which photon maps are
503                  * missing so (s)he can check geometry and materials */
504                 if (++prePassCnt > maxPreDistrib) {
505 <                  sprintf(errmsg,
413 <                          "proc %d, source %s: too many prepasses",
414 <                          proc, source [srcIdx].so -> oname);              
505 >                  sprintf(errmsg, "proc %d: too many prepasses", proc);
506  
507                    for (t = 0; t < NUM_PMAP_TYPES; t++)
508                       if (pmaps [t] && !pmaps [t] -> numPhotons) {
# Line 483 | Line 574 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
574                    break;
575              }
576  
577 <            /* Update shared completion counter for prog.report by parent */
577 >            /* Update shared completion counter for progreport by parent */
578              photonCnt -> numComplete += numEmit;                            
579  
580              /* PHOTON DISTRIBUTION LOOP */
# Line 496 | Line 587 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
587                                ? photonPorts + portCnt : NULL;
588                    photonPartition [emap.src -> so -> otype] (&emap);
589  
590 <                  if (photonRepTime && !proc) {
590 >                  if (verbose && !proc) {
591 >                     /* Output from subproc 0 only to avoid race condition
592 >                      * on console I/O */
593                       if (!passCnt)
594 <                        sprintf(errmsg, "PREPASS %d on source %s ",
594 >                        sprintf(errmsg, "\tPREPASS %d on source %s ",
595                                  prePassCnt, source [srcIdx].so -> oname);
596                       else
597 <                        sprintf(errmsg, "MAIN PASS on source %s ",
597 >                        sprintf(errmsg, "\tMAIN PASS on source %s ",
598                                  source [srcIdx].so -> oname);
599 <                            
599 >
600                       if (emap.port) {
601                          sprintf(errmsg2, "via port %s ",
602                                  photonPorts [portCnt].so -> oname);
603                          strcat(errmsg, errmsg2);
604                       }
605 <                    
605 >
606                       sprintf(errmsg2, "(%lu partitions)\n",
607                               emap.numPartitions);
608                       strcat(errmsg, errmsg2);
609                       eputs(errmsg);
610 + #if NIX                    
611                       fflush(stderr);
612 + #endif                    
613                    }
614                    
615                    for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions;
# Line 529 | Line 624 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
624                      
625                       /* Number of photons to emit from ziss partishunn --
626                        * proportional to flux; photon ray weight and scalar
627 <                      * flux are uniform (the latter only varying in RGB).
533 <                      * */
627 >                      * flux are uniform (latter only varying in RGB). */
628                       partNumEmit = numEmit * colorAvg(emap.partFlux) /
629                                     totalFlux;
630                       partEmitCnt = (unsigned long)partNumEmit;
# Line 551 | Line 645 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
645                          /* Emit photon based on PDF and trace through scene
646                           * until absorbed/leaked */
647                          emitPhoton(&emap, &photonRay);
648 + #if 1
649 +                        if (emap.port)
650 +                           /* !!!  PHOTON PORT REJECTION SAMPLING HACK: set
651 +                            * !!!  photon port as fake hit object for
652 +                            * !!!  primary ray to check for intersection in
653 +                            * !!!  tracePhoton() */
654 +                           photonRay.ro = emap.port -> so;
655 + #endif
656                          tracePhoton(&photonRay);
657                       }                                          
658 <                    
658 >
659                       /* Update shared global photon count for each pmap */
660                       for (t = 0; t < NUM_PMAP_TYPES; t++)
661                          if (pmaps [t]) {
# Line 561 | Line 663 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
663                                pmaps [t] -> numPhotons - lastNumPhotons [t];
664                             lastNumPhotons [t] = pmaps [t] -> numPhotons;
665                          }
666 + #if !NIX
667 +                     /* Synchronous progress report on Windoze */
668 +                     if (!proc && photonRepTime > 0 &&
669 +                           time(NULL) >= repLastTime + photonRepTime) {
670 +                        repEmitted = repProgress = photonCnt -> numEmitted;
671 +                        repComplete = photonCnt -> numComplete;                          
672 +                        pmapDistribReport();
673 +                     }
674 + #endif
675                    }
676                    
677                    portCnt++;
# Line 576 | Line 687 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
687                    break;
688                 }
689              
690 <            if (t >= NUM_PMAP_TYPES) {
690 >            if (t >= NUM_PMAP_TYPES)
691                 /* No empty photon maps found; now do pass 2 */
692                 passCnt++;
582 #if 0
583               if (photonRepTime)
584                  eputs("\n");
585 #endif
586            }
693           } while (passCnt < 2);
694          
695 <         /* Unmap shared photon counters */
696 < #if 0        
591 <         munmap(photonCnt, sizeof(*photonCnt));
592 <         close(shmFile);
593 < #endif
594 <        
595 <         /* Flush heap buffa for every pmap one final time; this is required
596 <          * to prevent data corruption! */
695 >         /* Flush heap buffa for every pmap one final time;
696 >          * avoids potential data corruption! */
697           for (t = 0; t < NUM_PMAP_TYPES; t++)
698              if (pmaps [t]) {
599 #if 0            
600               eputs("Final flush\n");
601 #endif              
699                 flushPhotonHeap(pmaps [t]);
700 <               fclose(pmaps [t] -> heap);
700 >               /* Heap file closed automatically on exit
701 >                  fclose(pmaps [t] -> heap); */
702   #ifdef DEBUG_PMAP              
703 <               sprintf(errmsg, "Proc %d: total %ld photons\n", getpid(),
703 >               sprintf(errmsg, "Proc %d: total %ld photons\n", proc,
704                         pmaps [t] -> numPhotons);
705                 eputs(errmsg);
706   #endif              
707              }
708 <
708 > #if NIX
709 >         /* Terminate subprocess */
710           exit(0);
711 + #endif
712        }
713        else if (pid < 0)
714           error(SYSTEM, "failed to fork subprocess in distribPhotons");        
715     }
716  
717 + #if NIX
718     /* PARENT PROCESS CONTINUES HERE */
618   /* Record start time and enable progress report signal handler */
619   repStartTime = time(NULL);
719   #ifdef SIGCONT
720 +   /* Enable progress report signal handler */
721     signal(SIGCONT, pmapDistribReport);
722 < #endif
723 <  
624 <   if (photonRepTime)
625 <      eputs("\n");
626 <  
627 <   /* Wait for subprocesses to complete while reporting progress */
722 > #endif  
723 >   /* Wait for subprocesses complete while reporting progress */
724     proc = numProc;
725     while (proc) {
726        while (waitpid(-1, &stat, WNOHANG) > 0) {
# Line 637 | Line 733 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
733        
734        /* Nod off for a bit and update progress  */
735        sleep(1);
736 <      /* Update progress report from shared subprocess counters */
736 >
737 >      /* Asynchronous progress report from shared subprocess counters */  
738        repEmitted = repProgress = photonCnt -> numEmitted;
739 <      repComplete = photonCnt -> numComplete;
739 >      repComplete = photonCnt -> numComplete;      
740  
741 +      repProgress = repComplete = 0;
742        for (t = 0; t < NUM_PMAP_TYPES; t++)
743           if ((pm = pmaps [t])) {
646 #if 0        
647            /* Get photon count from heapfile size for progress update */
648            fseek(pm -> heap, 0, SEEK_END);
649            pm -> numPhotons = ftell(pm -> heap) / sizeof(Photon); */
650 #else            
744              /* Get global photon count from shmem updated by subprocs */
745 <            pm -> numPhotons = photonCnt -> numPhotons [t];
746 < #endif            
745 >            repProgress += pm -> numPhotons = photonCnt -> numPhotons [t];
746 >            repComplete += pm -> distribTarget;
747           }
748 +      repComplete *= numProc;
749  
750        if (photonRepTime > 0 && time(NULL) >= repLastTime + photonRepTime)
751           pmapDistribReport();
# Line 659 | Line 753 | void distribPhotons (PhotonMap **pmaps, unsigned numPr
753        else signal(SIGCONT, pmapDistribReport);
754   #endif
755     }
756 + #endif /* NIX */
757  
758     /* ===================================================================
759      * POST-DISTRIBUTION - Set photon flux and build data struct for photon
760      * storage, etc.
761      * =================================================================== */
762   #ifdef SIGCONT    
763 +   /* Reset signal handler */
764     signal(SIGCONT, SIG_DFL);
765   #endif
766     free(emap.samples);
767    
768 <   /* Set photon flux (repProgress is total num emitted) */
768 >   /* Set photon flux */
769     totalFlux /= photonCnt -> numEmitted;
770 <  
770 > #if NIX  
771     /* Photon counters no longer needed, unmap shared memory */
772     munmap(photonCnt, sizeof(*photonCnt));
773     close(shmFile);
678 #if 0  
679   shm_unlink(shmFname);
680 #else
774     unlink(shmFname);
775 + #else
776 +   free(photonCnt);  
777   #endif      
778 <  
778 >   if (verbose)
779 >      eputs("\n");
780 >      
781     for (t = 0; t < NUM_PMAP_TYPES; t++)
782        if (pmaps [t]) {
783 <         if (photonRepTime) {
784 <            sprintf(errmsg, "\nBuilding %s photon map...\n", pmapName [t]);
783 >         if (verbose) {
784 >            sprintf(errmsg, "Building %s photon map\n", pmapName [t]);
785              eputs(errmsg);
786 + #if NIX            
787              fflush(stderr);
788 + #endif            
789           }
790          
791           /* Build underlying data structure; heap is destroyed */
792           buildPhotonMap(pmaps [t], &totalFlux, NULL, numProc);
793        }
794 <
794 >      
795     /* Precompute photon irradiance if necessary */
796 <   if (preCompPmap)
796 >   if (preCompPmap) {
797 >      if (verbose)
798 >         eputs("\n");
799        preComputeGlobal(preCompPmap);
800 +   }      
801 +  
802 +   if (verbose)
803 +      eputs("\n");
804   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines