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

Comparing ray/src/rt/pmapdata.c (file contents):
Revision 2.17 by greg, Thu Sep 29 20:51:07 2016 UTC vs.
Revision 2.18 by rschregle, Mon Aug 14 21:12:10 2017 UTC

# Line 22 | Line 22 | static const char RCSid[] = "$Id$";
22  
23  
24  
25 < #include "pmap.h"
25 > #include "pmapdata.h"
26   #include "pmaprand.h"
27   #include "pmapmat.h"
28   #include "otypes.h"
# Line 70 | Line 70 | void initPhotonMap (PhotonMap *pmap, PhotonMapType t)
70     pmap -> randState [0] = 10243;
71     pmap -> randState [1] = 39829;
72     pmap -> randState [2] = 9433;
73   /* pmapSeed(25999, pmap -> randState); */
73     pmapSeed(randSeed, pmap -> randState);
74    
75     /* Set up type-specific photon lookup callback */
# Line 103 | Line 102 | void initPhotonHeap (PhotonMap *pmap)
102        
103     if (!pmap -> heap) {
104        /* Open heap file */
105 <      if (!(pmap -> heap = tmpfile()))
105 >      mktemp(strcpy(pmap -> heapFname, PMAP_TMPFNAME));
106 >      if (!(pmap -> heap = fopen(pmap -> heapFname, "w+b")))
107           error(SYSTEM, "failed opening heap file in initPhotonHeap");
108 +
109   #ifdef F_SETFL  /* XXX is there an alternate needed for Windows? */
110        fdFlags = fcntl(fileno(pmap -> heap), F_GETFL);
111        fcntl(fileno(pmap -> heap), F_SETFL, fdFlags | O_APPEND);
112 < #endif
112 < /*      ftruncate(fileno(pmap -> heap), 0); */
112 > #endif/*      ftruncate(fileno(pmap -> heap), 0); */
113     }
114   }
115  
# Line 123 | Line 123 | void flushPhotonHeap (PhotonMap *pmap)
123     if (!pmap)
124        error(INTERNAL, "undefined photon map in flushPhotonHeap");
125  
126 <   if (!pmap -> heap || !pmap -> heapBuf)
127 <      error(INTERNAL, "undefined heap in flushPhotonHeap");
126 >   if (!pmap -> heap || !pmap -> heapBuf) {
127 >      /* Silently ignore undefined heap
128 >      error(INTERNAL, "undefined heap in flushPhotonHeap"); */
129 >      return;
130 >   }
131  
132     /* Atomically seek and write block to heap */
133     /* !!! Unbuffered I/O via pwrite() avoids potential race conditions
# Line 142 | Line 145 | void flushPhotonHeap (PhotonMap *pmap)
145     if (write(fd, pmap -> heapBuf, len) != len)
146        error(SYSTEM, "failed append to heap file in flushPhotonHeap");
147  
148 < #if !defined(_WIN32) && !defined(_WIN64)
148 > #if NIX
149     if (fsync(fd))
150        error(SYSTEM, "failed fsync in flushPhotonHeap");
151   #endif
152 +
153     pmap -> heapBufLen = 0;
154   }
155  
156  
157  
158 < #ifdef DEBUG_OOC
158 > #ifdef DEBUG_PMAP
159   static int checkPhotonHeap (FILE *file)
160   /* Check heap for nonsensical or duplicate photons */
161   {
# Line 192 | Line 196 | static int checkPhotonHeap (FILE *file)
196  
197   int newPhoton (PhotonMap* pmap, const RAY* ray)
198   {
199 <   unsigned i;
199 >   unsigned i, inROI = 0;
200     Photon photon;
201     COLOR photonFlux;
202    
# Line 204 | Line 208 | int newPhoton (PhotonMap* pmap, const RAY* ray)
208     if (ray -> robj > -1 && islight(objptr(ray -> ro -> omod) -> otype))
209        return -1;
210  
211 < #ifdef PMAP_ROI
212 <   /* Store photon if within region of interest -- for Ze Eckspertz only! */
213 <   if (ray -> rop [0] >= pmapROI [0] && ray -> rop [0] <= pmapROI [1] &&
214 <       ray -> rop [1] >= pmapROI [2] && ray -> rop [1] <= pmapROI [3] &&
215 <       ray -> rop [2] >= pmapROI [4] && ray -> rop [2] <= pmapROI [5])
216 < #endif
217 <   {      
211 >   /* Store photon if within a region of interest (for ze Ecksperts!) */
212 >   if (!pmapNumROI || !pmapROI)
213 >      inROI = 1;
214 >   else {
215 >      for (i = 0; !inROI && i < pmapNumROI; i++)
216 >         inROI = (ray -> rop [0] >= pmapROI [i].min [0] &&
217 >                  ray -> rop [0] <= pmapROI [i].max [0] &&
218 >                  ray -> rop [1] >= pmapROI [i].min [1] &&
219 >                  ray -> rop [1] <= pmapROI [i].max [1] &&
220 >                  ray -> rop [2] >= pmapROI [i].min [2] &&
221 >                  ray -> rop [2] <= pmapROI [i].max [2]);
222 >   }
223 >    
224 >   if (inROI) {      
225        /* Adjust flux according to distribution ratio and ray weight */
226        copycolor(photonFlux, ray -> rcol);  
227        scalecolor(photonFlux,
# Line 241 | Line 252 | int newPhoton (PhotonMap* pmap, const RAY* ray)
252  
253        if (!pmap -> heapBuf) {
254           /* Lazily allocate heap buffa */
255 < #if 1        
256 <         /* Randomise buffa size to temporally decorellate buffa flushes */        
255 > #if NIX
256 >         /* Randomise buffa size to temporally decorellate flushes in
257 >          * multiprocessing mode */
258           srandom(randSeed + getpid());
259           pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
260   #else
261 <         /* Randomisation disabled for reproducability during debugging */        
261 >         /* Randomisation disabled for single processes on WIN; also useful
262 >          * for reproducability during debugging */        
263           pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
264   #endif        
265           if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
# Line 276 | Line 289 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
289     unsigned       i;
290     Photon         *p;
291     COLOR          flux;
292 +   char           nuHeapFname [sizeof(PMAP_TMPFNAME)];
293     FILE           *nuHeap;
294     /* Need double here to reduce summation errors */
295     double         avgFlux [3] = {0, 0, 0}, CoG [3] = {0, 0, 0}, CoGdist = 0;
# Line 285 | Line 299 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
299        error(INTERNAL, "undefined photon map in buildPhotonMap");
300        
301     /* Get number of photons from heapfile size */
302 <   fseek(pmap -> heap, 0, SEEK_END);      
302 >   if (fseek(pmap -> heap, 0, SEEK_END) < 0)
303 >      error(SYSTEM, "failed seek to end of photon heap in buildPhotonMap");
304     pmap -> numPhotons = ftell(pmap -> heap) / sizeof(Photon);
305    
306     if (!pmap -> numPhotons)
# Line 301 | Line 316 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
316     sprintf(errmsg, "Heap contains %ld photons\n", pmap -> numPhotons);
317     eputs(errmsg);
318   #endif
319 <    
319 >
320     /* Allocate heap buffa */
321     if (!pmap -> heapBuf) {
322        pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
# Line 313 | Line 328 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
328  
329     /* We REALLY don't need yet another @%&*! heap just to hold the scaled
330      * photons, but can't think of a quicker fix... */
331 <   if (!(nuHeap = tmpfile()))
331 >   mktemp(strcpy(nuHeapFname, PMAP_TMPFNAME));
332 >   if (!(nuHeap = fopen(nuHeapFname, "w+b")))
333        error(SYSTEM, "failed to open postprocessed photon heap in "
334              "buildPhotonMap");
335              
# Line 323 | Line 339 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
339     eputs("Postprocessing photons...\n");
340   #endif
341    
342 <   while (!feof(pmap -> heap)) {
342 >   while (!feof(pmap -> heap)) {  
343 > #ifdef DEBUG_PMAP
344 >      printf("Reading %lu at %lu... ", pmap -> heapBufSize, ftell(pmap->heap));
345 > #endif      
346        pmap -> heapBufLen = fread(pmap -> heapBuf, sizeof(Photon),
347 <                                 PMAP_HEAPBUFSIZE, pmap -> heap);
348 <      
349 <      if (pmap -> heapBufLen) {
350 <         for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
332 <            /* Update min and max pos and set photon flux */
333 <            for (i = 0; i <= 2; i++) {
334 <               if (p -> pos [i] < pmap -> minPos [i])
335 <                  pmap -> minPos [i] = p -> pos [i];
336 <               else if (p -> pos [i] > pmap -> maxPos [i])
337 <                  pmap -> maxPos [i] = p -> pos [i];  
347 >                                 pmap -> heapBufSize, pmap -> heap);
348 > #ifdef DEBUG_PMAP                                
349 >      printf("Got %lu\n", pmap -> heapBufLen);
350 > #endif      
351  
352 <               /* Update centre of gravity with photon position */                
353 <               CoG [i] += p -> pos [i];                  
341 <            }  
342 <            
343 <            if (primaryOfs)
344 <               /* Linearise photon primary index from subprocess index using the
345 <                * per-subprocess offsets in primaryOfs */
346 <               p -> primary += primaryOfs [p -> proc];
347 <            
348 <            /* Scale photon's flux (hitherto normalised to 1 over RGB); in
349 <             * case of a contrib photon map, this is done per light source,
350 <             * and photonFlux is assumed to be an array */
351 <            getPhotonFlux(p, flux);            
352 >      if (ferror(pmap -> heap))
353 >         error(SYSTEM, "failed to read photon heap in buildPhotonMap");
354  
355 <            if (photonFlux) {
356 <               scalecolor(flux, photonFlux [isContribPmap(pmap) ?
357 <                                               photonSrcIdx(pmap, p) : 0]);
358 <               setPhotonFlux(p, flux);
359 <            }
355 >      for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
356 >         /* Update min and max pos and set photon flux */
357 >         for (i = 0; i <= 2; i++) {
358 >            if (p -> pos [i] < pmap -> minPos [i])
359 >               pmap -> minPos [i] = p -> pos [i];
360 >            else if (p -> pos [i] > pmap -> maxPos [i])
361 >               pmap -> maxPos [i] = p -> pos [i];  
362  
363 <            /* Update average photon flux; need a double here */
364 <            addcolor(avgFlux, flux);
363 >            /* Update centre of gravity with photon position */                
364 >            CoG [i] += p -> pos [i];                  
365 >         }  
366 >        
367 >         if (primaryOfs)
368 >            /* Linearise photon primary index from subprocess index using the
369 >             * per-subprocess offsets in primaryOfs */
370 >            p -> primary += primaryOfs [p -> proc];
371 >        
372 >         /* Scale photon's flux (hitherto normalised to 1 over RGB); in
373 >          * case of a contrib photon map, this is done per light source,
374 >          * and photonFlux is assumed to be an array */
375 >         getPhotonFlux(p, flux);            
376 >
377 >         if (photonFlux) {
378 >            scalecolor(flux, photonFlux [isContribPmap(pmap) ?
379 >                                            photonSrcIdx(pmap, p) : 0]);
380 >            setPhotonFlux(p, flux);
381           }
382 +
383 +         /* Update average photon flux; need a double here */
384 +         addcolor(avgFlux, flux);
385 +      }
386          
387 <         /* Write modified photons to new heap */
388 <         fwrite(pmap -> heapBuf, sizeof(Photon), pmap -> heapBufLen, nuHeap);
387 >      /* Write modified photons to new heap */
388 >      fwrite(pmap -> heapBuf, sizeof(Photon), pmap -> heapBufLen, nuHeap);
389                  
390 <         if (ferror(nuHeap))
391 <            error(SYSTEM, "failed postprocessing photon flux in "
392 <                  "buildPhotonMap");
369 <      }
390 >      if (ferror(nuHeap))
391 >         error(SYSTEM, "failed postprocessing photon flux in "
392 >               "buildPhotonMap");
393        
394        nCheck += pmap -> heapBufLen;
395     }
# Line 389 | Line 412 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
412     /* Compute average photon distance to centre of gravity */
413     while (!feof(pmap -> heap)) {
414        pmap -> heapBufLen = fread(pmap -> heapBuf, sizeof(Photon),
415 <                                 PMAP_HEAPBUFSIZE, pmap -> heap);
415 >                                 pmap -> heapBufSize, pmap -> heap);
416        
417 <      if (pmap -> heapBufLen)
418 <         for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
419 <            VSUB(d, p -> pos, CoG);
420 <            CoGdist += DOT(d, d);
398 <         }
417 >      for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
418 >         VSUB(d, p -> pos, CoG);
419 >         CoGdist += DOT(d, d);
420 >      }
421     }  
422  
423     pmap -> CoGdist = CoGdist /= pmap -> numPhotons;
424  
425 <   /* Swap heaps */
425 >   /* Swap heaps, discarding unscaled photons */
426     fclose(pmap -> heap);
427 +   unlink(pmap -> heapFname);
428     pmap -> heap = nuHeap;
429 +   strcpy(pmap -> heapFname, nuHeapFname);
430    
431   #ifdef PMAP_OOC
432     OOC_BuildPhotonMap(pmap, nproc);
433   #else
410   /* kd-tree not parallelised */
434     kdT_BuildPhotonMap(pmap);
435   #endif
436  
437     /* Trash heap and its buffa */
438     free(pmap -> heapBuf);
439     fclose(pmap -> heap);
440 +   unlink(pmap -> heapFname);
441     pmap -> heap = NULL;
442     pmap -> heapBuf = NULL;
443   }
# Line 572 | Line 596 | void find1Photon (PhotonMap *pmap, const RAY* ray, Pho
596   void getPhoton (PhotonMap *pmap, PhotonIdx idx, Photon *photon)
597   {
598   #ifdef PMAP_OOC
599 <   if (OOC_GetPhoton(pmap, idx, photon))
576 <      
599 >   if (OOC_GetPhoton(pmap, idx, photon))      
600   #else
601     if (kdT_GetPhoton(pmap, idx, photon))
602   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines