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.15 by rschregle, Tue May 17 17:39:47 2016 UTC vs.
Revision 2.20 by rschregle, Fri Mar 8 17:25:17 2019 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 45 | Line 45 | PhotonMap *photonMaps [NUM_PMAP_TYPES] = {
45     #include "pmapkdt.c"
46   #endif
47  
48 + /* Ambient include/exclude set (from ambient.c) */
49 + #ifndef  MAXASET
50 +   #define MAXASET  4095
51 + #endif
52 + extern OBJECT ambset [MAXASET+1];
53  
54  
55 +
56   void initPhotonMap (PhotonMap *pmap, PhotonMapType t)
57   /* Init photon map 'n' stuff... */
58   {
# Line 70 | Line 76 | void initPhotonMap (PhotonMap *pmap, PhotonMapType t)
76     pmap -> randState [0] = 10243;
77     pmap -> randState [1] = 39829;
78     pmap -> randState [2] = 9433;
73   /* pmapSeed(25999, pmap -> randState); */
79     pmapSeed(randSeed, pmap -> randState);
80    
81     /* Set up type-specific photon lookup callback */
# Line 103 | Line 108 | void initPhotonHeap (PhotonMap *pmap)
108        
109     if (!pmap -> heap) {
110        /* Open heap file */
111 <      if (!(pmap -> heap = tmpfile()))
111 >      mktemp(strcpy(pmap -> heapFname, PMAP_TMPFNAME));
112 >      if (!(pmap -> heap = fopen(pmap -> heapFname, "w+b")))
113           error(SYSTEM, "failed opening heap file in initPhotonHeap");
114 +
115 + #ifdef F_SETFL  /* XXX is there an alternate needed for Windows? */
116        fdFlags = fcntl(fileno(pmap -> heap), F_GETFL);
117        fcntl(fileno(pmap -> heap), F_SETFL, fdFlags | O_APPEND);
118 < /*      ftruncate(fileno(pmap -> heap), 0); */
118 > #endif/*      ftruncate(fileno(pmap -> heap), 0); */
119     }
120   }
121  
# Line 121 | Line 129 | void flushPhotonHeap (PhotonMap *pmap)
129     if (!pmap)
130        error(INTERNAL, "undefined photon map in flushPhotonHeap");
131  
132 <   if (!pmap -> heap || !pmap -> heapBuf)
133 <      error(INTERNAL, "undefined heap in flushPhotonHeap");
132 >   if (!pmap -> heap || !pmap -> heapBuf) {
133 >      /* Silently ignore undefined heap
134 >      error(INTERNAL, "undefined heap in flushPhotonHeap"); */
135 >      return;
136 >   }
137  
138     /* Atomically seek and write block to heap */
139     /* !!! Unbuffered I/O via pwrite() avoids potential race conditions
# Line 139 | Line 150 | void flushPhotonHeap (PhotonMap *pmap)
150     /*if (pwrite(fd, pmap -> heapBuf, len, lseek(fd, 0, SEEK_END)) != len) */
151     if (write(fd, pmap -> heapBuf, len) != len)
152        error(SYSTEM, "failed append to heap file in flushPhotonHeap");
153 <  
153 >
154 > #if NIX
155     if (fsync(fd))
156        error(SYSTEM, "failed fsync in flushPhotonHeap");
157 <      
157 > #endif
158 >
159     pmap -> heapBufLen = 0;
160   }
161  
162  
163  
164 < #ifdef DEBUG_OOC
164 > #ifdef DEBUG_PMAP
165   static int checkPhotonHeap (FILE *file)
166   /* Check heap for nonsensical or duplicate photons */
167   {
# Line 201 | Line 214 | int newPhoton (PhotonMap* pmap, const RAY* ray)
214     if (ray -> robj > -1 && islight(objptr(ray -> ro -> omod) -> otype))
215        return -1;
216  
217 < #ifdef PMAP_ROI
218 <   /* Store photon if within region of interest -- for Ze Eckspertz only! */
219 <   if (ray -> rop [0] >= pmapROI [0] && ray -> rop [0] <= pmapROI [1] &&
220 <       ray -> rop [1] >= pmapROI [2] && ray -> rop [1] <= pmapROI [3] &&
208 <       ray -> rop [2] >= pmapROI [4] && ray -> rop [2] <= pmapROI [5])
209 < #endif
210 <   {      
211 <      /* Adjust flux according to distribution ratio and ray weight */
212 <      copycolor(photonFlux, ray -> rcol);  
213 <      scalecolor(photonFlux,
214 <                 ray -> rweight / (pmap -> distribRatio ? pmap -> distribRatio
215 <                                                        : 1));
216 <      setPhotonFlux(&photon, photonFlux);
217 <              
218 <      /* Set photon position and flags */
219 <      VCOPY(photon.pos, ray -> rop);
220 <      photon.flags = 0;
221 <      photon.caustic = PMAP_CAUSTICRAY(ray);
217 >   /* Ignore photon if modifier in/outside exclude/include set */
218 >   if (ambincl != -1 && ray -> ro &&
219 >       ambincl != inset(ambset, ray -> ro -> omod))
220 >      return -1;
221  
222 <      /* Set contrib photon's primary ray and subprocess index (the latter
223 <       * to linearise the primary ray indices after photon distribution is
225 <       * complete). Also set primary ray's source index, thereby marking it
226 <       * as used. */
227 <      if (isContribPmap(pmap)) {
228 <         photon.primary = pmap -> numPrimary;
229 <         photon.proc = PMAP_GETRAYPROC(ray);
230 <         pmap -> lastPrimary.srcIdx = ray -> rsrc;
231 <      }
232 <      else photon.primary = 0;
222 >   if (pmapNumROI && pmapROI) {      
223 >      unsigned inROI = 0;
224        
225 <      /* Set normal */
226 <      for (i = 0; i <= 2; i++)
227 <         photon.norm [i] = 127.0 * (isVolumePmap(pmap) ? ray -> rdir [i]
228 <                                                       : ray -> ron [i]);
225 >      /* Store photon if within a region of interest (for ze Ecksperts!) */
226 >      for (i = 0; !inROI && i < pmapNumROI; i++)
227 >         inROI = (ray -> rop [0] >= pmapROI [i].min [0] &&
228 >                  ray -> rop [0] <= pmapROI [i].max [0] &&
229 >                  ray -> rop [1] >= pmapROI [i].min [1] &&
230 >                  ray -> rop [1] <= pmapROI [i].max [1] &&
231 >                  ray -> rop [2] >= pmapROI [i].min [2] &&
232 >                  ray -> rop [2] <= pmapROI [i].max [2]);
233 >      if (!inROI)
234 >         return -1;
235 >   }
236 >  
237 >   /* Adjust flux according to distribution ratio and ray weight */
238 >   copycolor(photonFlux, ray -> rcol);  
239 >   scalecolor(photonFlux,
240 >              ray -> rweight / (pmap -> distribRatio ? pmap -> distribRatio
241 >                                                     : 1));
242 >   setPhotonFlux(&photon, photonFlux);
243  
244 <      if (!pmap -> heapBuf) {
245 <         /* Lazily allocate heap buffa */
246 < #if 1        
247 <         /* Randomise buffa size to temporally decorellate buffa flushes */        
248 <         srandom(randSeed + getpid());
249 <         pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
244 >   /* Set photon position and flags */
245 >   VCOPY(photon.pos, ray -> rop);
246 >   photon.flags = 0;
247 >   photon.caustic = PMAP_CAUSTICRAY(ray);
248 >
249 >   /* Set contrib photon's primary ray and subprocess index (the latter
250 >    * to linearise the primary ray indices after photon distribution is
251 >    * complete). Also set primary ray's source index, thereby marking it
252 >    * as used. */
253 >   if (isContribPmap(pmap)) {
254 >      photon.primary = pmap -> numPrimary;
255 >      photon.proc = PMAP_GETRAYPROC(ray);
256 >      pmap -> lastPrimary.srcIdx = ray -> rsrc;
257 >   }
258 >   else photon.primary = 0;
259 >  
260 >   /* Set normal */
261 >   for (i = 0; i <= 2; i++)
262 >      photon.norm [i] = 127.0 * (isVolumePmap(pmap) ? ray -> rdir [i]
263 >                                                    : ray -> ron [i]);
264 >
265 >   if (!pmap -> heapBuf) {
266 >      /* Lazily allocate heap buffa */
267 > #if NIX
268 >      /* Randomise buffa size to temporally decorellate flushes in
269 >       * multiprocessing mode */
270 >      srandom(randSeed + getpid());
271 >      pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
272   #else
273 <         /* Randomisation disabled for reproducability during debugging */        
274 <         pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
273 >      /* Randomisation disabled for single processes on WIN; also useful
274 >       * for reproducability during debugging */        
275 >      pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
276   #endif        
277 <         if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
278 <            error(SYSTEM, "failed heap buffer allocation in newPhoton");
279 <         pmap -> heapBufLen = 0;      
280 <      }
277 >      if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
278 >         error(SYSTEM, "failed heap buffer allocation in newPhoton");
279 >      pmap -> heapBufLen = 0;      
280 >   }
281  
282 <      /* Photon initialised; now append to heap buffa */
283 <      memcpy(pmap -> heapBuf + pmap -> heapBufLen, &photon, sizeof(Photon));
284 <                  
285 <      if (++pmap -> heapBufLen >= pmap -> heapBufSize)
286 <         /* Heap buffa full, flush to heap file */
287 <         flushPhotonHeap(pmap);
282 >   /* Photon initialised; now append to heap buffa */
283 >   memcpy(pmap -> heapBuf + pmap -> heapBufLen, &photon, sizeof(Photon));
284 >              
285 >   if (++pmap -> heapBufLen >= pmap -> heapBufSize)
286 >      /* Heap buffa full, flush to heap file */
287 >      flushPhotonHeap(pmap);
288  
289 <      pmap -> numPhotons++;
262 <   }
289 >   pmap -> numPhotons++;
290              
291     return 0;
292   }
# Line 273 | Line 300 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
300     unsigned       i;
301     Photon         *p;
302     COLOR          flux;
303 +   char           nuHeapFname [sizeof(PMAP_TMPFNAME)];
304     FILE           *nuHeap;
305     /* Need double here to reduce summation errors */
306     double         avgFlux [3] = {0, 0, 0}, CoG [3] = {0, 0, 0}, CoGdist = 0;
# Line 282 | Line 310 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
310        error(INTERNAL, "undefined photon map in buildPhotonMap");
311        
312     /* Get number of photons from heapfile size */
313 <   fseek(pmap -> heap, 0, SEEK_END);      
313 >   if (fseek(pmap -> heap, 0, SEEK_END) < 0)
314 >      error(SYSTEM, "failed seek to end of photon heap in buildPhotonMap");
315     pmap -> numPhotons = ftell(pmap -> heap) / sizeof(Photon);
316    
317     if (!pmap -> numPhotons)
# Line 298 | Line 327 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
327     sprintf(errmsg, "Heap contains %ld photons\n", pmap -> numPhotons);
328     eputs(errmsg);
329   #endif
330 <    
330 >
331     /* Allocate heap buffa */
332     if (!pmap -> heapBuf) {
333        pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
# Line 310 | Line 339 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
339  
340     /* We REALLY don't need yet another @%&*! heap just to hold the scaled
341      * photons, but can't think of a quicker fix... */
342 <   if (!(nuHeap = tmpfile()))
342 >   mktemp(strcpy(nuHeapFname, PMAP_TMPFNAME));
343 >   if (!(nuHeap = fopen(nuHeapFname, "w+b")))
344        error(SYSTEM, "failed to open postprocessed photon heap in "
345              "buildPhotonMap");
346              
# Line 320 | Line 350 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
350     eputs("Postprocessing photons...\n");
351   #endif
352    
353 <   while (!feof(pmap -> heap)) {
353 >   while (!feof(pmap -> heap)) {  
354 > #ifdef DEBUG_PMAP
355 >      printf("Reading %lu at %lu... ", pmap -> heapBufSize, ftell(pmap->heap));
356 > #endif      
357        pmap -> heapBufLen = fread(pmap -> heapBuf, sizeof(Photon),
358 <                                 PMAP_HEAPBUFSIZE, pmap -> heap);
359 <      
360 <      if (pmap -> heapBufLen) {
361 <         for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
329 <            /* Update min and max pos and set photon flux */
330 <            for (i = 0; i <= 2; i++) {
331 <               if (p -> pos [i] < pmap -> minPos [i])
332 <                  pmap -> minPos [i] = p -> pos [i];
333 <               else if (p -> pos [i] > pmap -> maxPos [i])
334 <                  pmap -> maxPos [i] = p -> pos [i];  
358 >                                 pmap -> heapBufSize, pmap -> heap);
359 > #ifdef DEBUG_PMAP                                
360 >      printf("Got %lu\n", pmap -> heapBufLen);
361 > #endif      
362  
363 <               /* Update centre of gravity with photon position */                
364 <               CoG [i] += p -> pos [i];                  
338 <            }  
339 <            
340 <            if (primaryOfs)
341 <               /* Linearise photon primary index from subprocess index using the
342 <                * per-subprocess offsets in primaryOfs */
343 <               p -> primary += primaryOfs [p -> proc];
344 <            
345 <            /* Scale photon's flux (hitherto normalised to 1 over RGB); in
346 <             * case of a contrib photon map, this is done per light source,
347 <             * and photonFlux is assumed to be an array */
348 <            getPhotonFlux(p, flux);            
363 >      if (ferror(pmap -> heap))
364 >         error(SYSTEM, "failed to read photon heap in buildPhotonMap");
365  
366 <            if (photonFlux) {
367 <               scalecolor(flux, photonFlux [isContribPmap(pmap) ?
368 <                                               photonSrcIdx(pmap, p) : 0]);
369 <               setPhotonFlux(p, flux);
370 <            }
366 >      for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
367 >         /* Update min and max pos and set photon flux */
368 >         for (i = 0; i <= 2; i++) {
369 >            if (p -> pos [i] < pmap -> minPos [i])
370 >               pmap -> minPos [i] = p -> pos [i];
371 >            else if (p -> pos [i] > pmap -> maxPos [i])
372 >               pmap -> maxPos [i] = p -> pos [i];  
373  
374 <            /* Update average photon flux; need a double here */
375 <            addcolor(avgFlux, flux);
374 >            /* Update centre of gravity with photon position */                
375 >            CoG [i] += p -> pos [i];                  
376 >         }  
377 >        
378 >         if (primaryOfs)
379 >            /* Linearise photon primary index from subprocess index using the
380 >             * per-subprocess offsets in primaryOfs */
381 >            p -> primary += primaryOfs [p -> proc];
382 >        
383 >         /* Scale photon's flux (hitherto normalised to 1 over RGB); in
384 >          * case of a contrib photon map, this is done per light source,
385 >          * and photonFlux is assumed to be an array */
386 >         getPhotonFlux(p, flux);
387 >
388 >         if (photonFlux) {
389 >            scalecolor(flux, photonFlux [isContribPmap(pmap) ?
390 >                                            photonSrcIdx(pmap, p) : 0]);
391 >            setPhotonFlux(p, flux);
392           }
393 +
394 +         /* Update average photon flux; need a double here */
395 +         addcolor(avgFlux, flux);
396 +      }
397          
398 <         /* Write modified photons to new heap */
399 <         fwrite(pmap -> heapBuf, sizeof(Photon), pmap -> heapBufLen, nuHeap);
398 >      /* Write modified photons to new heap */
399 >      fwrite(pmap -> heapBuf, sizeof(Photon), pmap -> heapBufLen, nuHeap);
400                  
401 <         if (ferror(nuHeap))
402 <            error(SYSTEM, "failed postprocessing photon flux in "
403 <                  "buildPhotonMap");
366 <      }
401 >      if (ferror(nuHeap))
402 >         error(SYSTEM, "failed postprocessing photon flux in "
403 >               "buildPhotonMap");
404        
405        nCheck += pmap -> heapBufLen;
406     }
# Line 386 | Line 423 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
423     /* Compute average photon distance to centre of gravity */
424     while (!feof(pmap -> heap)) {
425        pmap -> heapBufLen = fread(pmap -> heapBuf, sizeof(Photon),
426 <                                 PMAP_HEAPBUFSIZE, pmap -> heap);
426 >                                 pmap -> heapBufSize, pmap -> heap);
427        
428 <      if (pmap -> heapBufLen)
429 <         for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
430 <            VSUB(d, p -> pos, CoG);
431 <            CoGdist += DOT(d, d);
395 <         }
428 >      for (n = pmap -> heapBufLen, p = pmap -> heapBuf; n; n--, p++) {
429 >         VSUB(d, p -> pos, CoG);
430 >         CoGdist += DOT(d, d);
431 >      }
432     }  
433  
434     pmap -> CoGdist = CoGdist /= pmap -> numPhotons;
435  
436 <   /* Swap heaps */
436 >   /* Swap heaps, discarding unscaled photons */
437     fclose(pmap -> heap);
438 +   unlink(pmap -> heapFname);
439     pmap -> heap = nuHeap;
440 +   strcpy(pmap -> heapFname, nuHeapFname);
441    
442   #ifdef PMAP_OOC
443     OOC_BuildPhotonMap(pmap, nproc);
444   #else
407   /* kd-tree not parallelised */
445     kdT_BuildPhotonMap(pmap);
446   #endif
447  
448     /* Trash heap and its buffa */
449     free(pmap -> heapBuf);
450     fclose(pmap -> heap);
451 +   unlink(pmap -> heapFname);
452     pmap -> heap = NULL;
453     pmap -> heapBuf = NULL;
454   }
# Line 569 | Line 607 | void find1Photon (PhotonMap *pmap, const RAY* ray, Pho
607   void getPhoton (PhotonMap *pmap, PhotonIdx idx, Photon *photon)
608   {
609   #ifdef PMAP_OOC
610 <   if (OOC_GetPhoton(pmap, idx, photon))
573 <      
610 >   if (OOC_GetPhoton(pmap, idx, photon))      
611   #else
612     if (kdT_GetPhoton(pmap, idx, photon))
613   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines