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.18 by rschregle, Mon Aug 14 21:12:10 2017 UTC vs.
Revision 2.23 by rschregle, Wed Apr 14 11:26:25 2021 UTC

# Line 13 | Line 13 | static const char RCSid[] = "$Id$";
13  
14     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
15     (c) Fraunhofer Institute for Solar Energy Systems,
16 +       supported by the German Research Foundation
17 +       (DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme" (FARESYS))
18     (c) Lucerne University of Applied Sciences and Arts,
19 <       supported by the Swiss National Science Foundation (SNSF, #147053)
19 >       supported by the Swiss National Science Foundation
20 >       (SNSF #147053, "Daylight Redirecting Components")
21     ==========================================================================
22    
23     $Id$
# Line 45 | Line 48 | PhotonMap *photonMaps [NUM_PMAP_TYPES] = {
48     #include "pmapkdt.c"
49   #endif
50  
51 + /* Ambient include/exclude set (from ambient.c) */
52 + #ifndef  MAXASET
53 +   #define MAXASET  4095
54 + #endif
55 + extern OBJECT ambset [MAXASET+1];
56  
57 + /* Callback to print photon attributes acc. to user defined format */
58 + int (*printPhoton)(RAY *r, Photon *p, PhotonMap *pm);
59  
60 +
61 +
62   void initPhotonMap (PhotonMap *pmap, PhotonMapType t)
63   /* Init photon map 'n' stuff... */
64   {
# Line 196 | Line 208 | static int checkPhotonHeap (FILE *file)
208  
209   int newPhoton (PhotonMap* pmap, const RAY* ray)
210   {
211 <   unsigned i, inROI = 0;
211 >   unsigned i;
212     Photon photon;
213     COLOR photonFlux;
214    
# Line 208 | Line 220 | int newPhoton (PhotonMap* pmap, const RAY* ray)
220     if (ray -> robj > -1 && islight(objptr(ray -> ro -> omod) -> otype))
221        return -1;
222  
223 <   /* Store photon if within a region of interest (for ze Ecksperts!) */
224 <   if (!pmapNumROI || !pmapROI)
225 <      inROI = 1;
226 <   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,
228 <                 ray -> rweight / (pmap -> distribRatio ? pmap -> distribRatio
229 <                                                        : 1));
230 <      setPhotonFlux(&photon, photonFlux);
231 <              
232 <      /* Set photon position and flags */
233 <      VCOPY(photon.pos, ray -> rop);
234 <      photon.flags = 0;
235 <      photon.caustic = PMAP_CAUSTICRAY(ray);
223 >   /* Ignore photon if modifier in/outside exclude/include set */
224 >   if (ambincl != -1 && ray -> ro &&
225 >       ambincl != inset(ambset, ray -> ro -> omod))
226 >      return -1;
227  
228 <      /* Set contrib photon's primary ray and subprocess index (the latter
229 <       * to linearise the primary ray indices after photon distribution is
230 <       * complete). Also set primary ray's source index, thereby marking it
240 <       * as used. */
241 <      if (isContribPmap(pmap)) {
242 <         photon.primary = pmap -> numPrimary;
243 <         photon.proc = PMAP_GETRAYPROC(ray);
244 <         pmap -> lastPrimary.srcIdx = ray -> rsrc;
245 <      }
246 <      else photon.primary = 0;
228 >   if (pmapNumROI && pmapROI) {
229 >      unsigned inROI = 0;
230 >      FVECT    photonDist;
231        
232 <      /* Set normal */
233 <      for (i = 0; i <= 2; i++)
234 <         photon.norm [i] = 127.0 * (isVolumePmap(pmap) ? ray -> rdir [i]
235 <                                                       : ray -> ron [i]);
232 >      /* Store photon if within a region of interest (for ze Ecksperts!)
233 >         Note size of spherical ROI is squared. */
234 >      for (i = 0; !inROI && i < pmapNumROI; i++) {
235 >         VSUB(photonDist, ray -> rop, pmapROI [i].pos);
236 >        
237 >         inROI = (
238 >            PMAP_ROI_ISSPHERE(pmapROI + i)
239 >            ?  DOT(photonDist, photonDist) <= pmapROI [i].siz [0]
240 >            :  fabs(photonDist [0]) <= pmapROI [i].siz [0] &&
241 >               fabs(photonDist [1]) <= pmapROI [i].siz [1] &&
242 >               fabs(photonDist [2]) <= pmapROI [i].siz [2]
243 >         );
244 >      }
245 >      if (!inROI)
246 >         return -1;
247 >   }
248 >  
249 >   /* Adjust flux according to distribution ratio and ray weight */
250 >   copycolor(photonFlux, ray -> rcol);        
251 > #if 0
252 >   /* Factored out ray -> rweight as deprecated (?) for pmap, and infact
253 >      erroneously attenuates volume photon flux based on extinction,
254 >      which is already factored in by photonParticipate() */
255 >   scalecolor(photonFlux,
256 >              ray -> rweight / (pmap -> distribRatio ? pmap -> distribRatio
257 >                                                     : 1));
258 > #else
259 >   scalecolor(photonFlux,
260 >              1.0 / (pmap -> distribRatio ? pmap -> distribRatio : 1));
261 > #endif
262 >   setPhotonFlux(&photon, photonFlux);
263  
264 <      if (!pmap -> heapBuf) {
265 <         /* Lazily allocate heap buffa */
264 >   /* Set photon position and flags */
265 >   VCOPY(photon.pos, ray -> rop);
266 >   photon.flags = 0;
267 >   photon.caustic = PMAP_CAUSTICRAY(ray);
268 >
269 >   /* Set contrib photon's primary ray and subprocess index (the latter
270 >    * to linearise the primary ray indices after photon distribution is
271 >    * complete). Also set primary ray's source index, thereby marking it
272 >    * as used. */
273 >   if (isContribPmap(pmap)) {
274 >      photon.primary = pmap -> numPrimary;
275 >      photon.proc = PMAP_GETRAYPROC(ray);
276 >      pmap -> lastPrimary.srcIdx = ray -> rsrc;
277 >   }
278 >   else photon.primary = 0;
279 >  
280 >   /* Set normal */
281 >   for (i = 0; i <= 2; i++)
282 >      photon.norm [i] = 127.0 * (isVolumePmap(pmap) ? ray -> rdir [i]
283 >                                                    : ray -> ron [i]);
284 >
285 >   if (!pmap -> heapBuf) {
286 >      /* Lazily allocate heap buffa */
287   #if NIX
288 <         /* Randomise buffa size to temporally decorellate flushes in
289 <          * multiprocessing mode */
290 <         srandom(randSeed + getpid());
291 <         pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
288 >      /* Randomise buffa size to temporally decorellate flushes in
289 >       * multiprocessing mode */
290 >      srandom(randSeed + getpid());
291 >      pmap -> heapBufSize = PMAP_HEAPBUFSIZE * (0.5 + frandom());
292   #else
293 <         /* Randomisation disabled for single processes on WIN; also useful
294 <          * for reproducability during debugging */        
295 <         pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
293 >      /* Randomisation disabled for single processes on WIN; also useful
294 >       * for reproducability during debugging */        
295 >      pmap -> heapBufSize = PMAP_HEAPBUFSIZE;
296   #endif        
297 <         if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
298 <            error(SYSTEM, "failed heap buffer allocation in newPhoton");
299 <         pmap -> heapBufLen = 0;      
300 <      }
297 >      if (!(pmap -> heapBuf = calloc(pmap -> heapBufSize, sizeof(Photon))))
298 >         error(SYSTEM, "failed heap buffer allocation in newPhoton");
299 >      pmap -> heapBufLen = 0;      
300 >   }
301  
302 <      /* Photon initialised; now append to heap buffa */
303 <      memcpy(pmap -> heapBuf + pmap -> heapBufLen, &photon, sizeof(Photon));
304 <                  
305 <      if (++pmap -> heapBufLen >= pmap -> heapBufSize)
306 <         /* Heap buffa full, flush to heap file */
307 <         flushPhotonHeap(pmap);
302 >   /* Photon initialised; now append to heap buffa */
303 >   memcpy(pmap -> heapBuf + pmap -> heapBufLen, &photon, sizeof(Photon));
304 >              
305 >   if (++pmap -> heapBufLen >= pmap -> heapBufSize)
306 >      /* Heap buffa full, flush to heap file */
307 >      flushPhotonHeap(pmap);
308  
309 <      pmap -> numPhotons++;
310 <   }
309 >   pmap -> numPhotons++;
310 >        
311 >   /* Print photon attributes */
312 >   if (printPhoton)
313 >      /* Non-const kludge */
314 >      printPhoton((RAY*)ray, &photon, pmap);
315              
316     return 0;
317   }
# Line 372 | Line 408 | void buildPhotonMap (PhotonMap *pmap, double *photonFl
408           /* Scale photon's flux (hitherto normalised to 1 over RGB); in
409            * case of a contrib photon map, this is done per light source,
410            * and photonFlux is assumed to be an array */
411 <         getPhotonFlux(p, flux);            
411 >         getPhotonFlux(p, flux);
412  
413           if (photonFlux) {
414              scalecolor(flux, photonFlux [isContribPmap(pmap) ?
# Line 490 | Line 526 | void findPhotons (PhotonMap* pmap, const RAY* ray)
526          
527        /* Search position is ray -> rorg for volume photons, since we have no
528           intersection point. Normals are ignored -- these are incident
529 <         directions). */  
529 >         directions). */
530 >      /* NOTE: status returned by XXX_FindPhotons() is currently ignored;
531 >         if no photons are found, an empty queue is returned under the
532 >         assumption all photons are too distant to contribute significant
533 >         flux. */
534        if (isVolumePmap(pmap)) {
535   #ifdef PMAP_OOC
536           OOC_FindPhotons(pmap, ray -> rorg, NULL);
# Line 580 | Line 620 | void findPhotons (PhotonMap* pmap, const RAY* ray)
620  
621  
622  
623 < void find1Photon (PhotonMap *pmap, const RAY* ray, Photon *photon)
623 > Photon *find1Photon (PhotonMap *pmap, const RAY* ray, Photon *photon)
624   {
625 <   pmap -> maxDist2 = thescene.cusize;  /* ? */
625 >   /* Init (squared) search radius to avg photon dist to centre of gravity */
626 >   float maxDist2_0 = pmap -> CoGdist;  
627 >   int found = 0;  
628 > #ifdef PMAP_LOOKUP_REDO
629 >   #define REDO 1
630 > #else
631 >   #define REDO 0
632 > #endif
633    
634 +   do {
635 +      pmap -> maxDist2 = maxDist2_0;
636   #ifdef PMAP_OOC
637 <   OOC_Find1Photon(pmap, ray -> rop, ray -> ron, photon);
637 >      found = OOC_Find1Photon(pmap, ray -> rop, ray -> ron, photon);
638   #else
639 <   kdT_Find1Photon(pmap, ray -> rop, ray -> ron, photon);
640 < #endif                  
639 >      found = kdT_Find1Photon(pmap, ray -> rop, ray -> ron, photon);
640 > #endif
641 >      if (found < 0) {
642 >         /* Expand search radius to retry */
643 >         maxDist2_0 *= 2;      
644 > #ifdef PMAP_LOOKUP_WARN
645 >         sprintf(errmsg, "failed 1-NN photon lookup"
646 > #ifdef PMAP_LOOKUP_REDO
647 >            ", retrying with search radius %.2f", maxDist2_0
648 > #endif
649 >         );
650 >         error(WARNING, errmsg);
651 > #endif
652 >      }
653 >   } while (REDO && found < 0);
654 >
655 >   /* Return photon buffer containing valid photon, else NULL */
656 >   return found < 0 ? NULL : photon;
657   }
658  
659  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines