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

Comparing ray/src/rt/pmapdump.c (file contents):
Revision 2.4 by greg, Tue Aug 18 18:45:55 2015 UTC vs.
Revision 2.13 by rschregle, Thu Jan 10 17:32:39 2019 UTC

# Line 1 | Line 1
1   #ifndef lint
2   static const char RCSid[] = "$Id$";
3   #endif
4 +
5   /*
6 <   ==================================================================
6 >   ======================================================================
7     Dump photon maps as RADIANCE scene description to stdout
8  
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Fraunhofer Institute for Solar Energy Systems,
11     (c) Lucerne University of Applied Sciences and Arts,
12 <   supported by the Swiss National Science Foundation (SNSF, #147053)
13 <   ==================================================================
12 >       supported by the Swiss National Science Foundation (SNSF, #147053)
13 >   ======================================================================
14    
15     $Id$
16   */
# Line 39 | Line 40 | typedef struct {
40     char *mat, *obj;
41   } RadianceDef;
42  
42  
43 static char header [] = "$Revision$";
43  
44 <
45 < /* Colour code is as follows:    global         = blue
47 <                                 precomp global = cyan
48 <                                 caustic        = red
49 <                                 volume         = green
50 <                                 direct         = magenta
51 <                                 contrib        = yellow */  
44 > /* We use %e for the material def to preserve precision when outputting
45 >   photon flux */
46   const RadianceDef radDefs [] = {
47 <   {  "void plastic mat.global\n0\n0\n5 0 0 1 0 0\n",
47 >   {  "void glow mat.global\n0\n0\n4 %e %e %e 0\n",
48        "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
49     },
50 <   {  "void plastic mat.pglobal\n0\n0\n5 0 1 1 0 0\n",
51 <      "mat.pglobal sphere obj.global\n0\n0\n4 %g %g %g %g\n"
50 >   {  "void glow mat.pglobal\n0\n0\n4 %e %e %e 0\n",
51 >      "mat.pglobal sphere obj.pglobal\n0\n0\n4 %g %g %g %g\n"
52     },
53 <   {  "void plastic mat.caustic\n0\n0\n5 1 0 0 0 0\n",
53 >   {  "void glow mat.caustic\n0\n0\n4 %e %e %e 0\n",
54        "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
55     },
56 <   {  "void plastic mat.volume\n0\n0\n5 0 1 0 0 0\n",
56 >   {  "void glow mat.volume\n0\n0\n4 %e %e %e 0\n",
57        "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
58     },
59 <   {  "void plastic mat.direct\n0\n0\n5 1 0 1 0 0\n",
59 >   {  "void glow mat.direct\n0\n0\n4 %e %e %e 0\n",
60        "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
61     },
62 <   {  "void plastic mat.contrib\n0\n0\n5 1 1 0 0 0\n",
62 >   {  "void glow mat.contrib\n0\n0\n4 %e %e %e 0\n",
63        "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
64     }
65   };
66  
67 + /* Default colour codes are as follows:   global         = blue
68 +                                          precomp global = cyan
69 +                                          caustic        = red
70 +                                          volume         = green
71 +                                          direct         = magenta
72 +                                          contrib        = yellow */
73 + const COLOR colDefs [] = {
74 +   {0.25, 0.25, 2}, {0.1, 1, 1}, {1, 0.1, 0.1},
75 +   {0.1, 1, 0.1}, {1, 0.1, 1}, {1, 1, 0.1}
76 + };
77  
78  
79   int main (int argc, char** argv)
80   {
81 <   char format [128];
82 <   RREAL rad, radScale = RADSCALE, vol, dumpRatio;
83 <   FVECT minPos, maxPos;
84 <   unsigned arg, j, ptype;
85 <   long numPhotons, numSpheres = NSPHERES;
86 <   FILE *pmapFile;
87 <   Photon p;
88 <  
81 >   char           format [MAXFMTLEN];
82 >   RREAL          rad, radScale = RADSCALE, extent, dumpRatio;
83 >   unsigned       arg, j, ptype, dim, fluxCol = 0;
84 >   long           numSpheres = NSPHERES;
85 >   COLOR          customCol = {0, 0, 0};
86 >   FILE           *pmapFile;
87 >   PhotonMap      pm;
88 >   PhotonPrimary  pri;
89 >   Photon         p;
90 > #ifdef PMAP_OOC
91 >   char           leafFname [1024];
92 > #endif
93 >
94 >   int setBool(char *str, int pos, int *var)
95 >   {
96 >      switch ((str) [pos]) {
97 >         case '\0':
98 >            *var = !*var;
99 >            break;
100 >         case 'y': case 'Y': case 't': case 'T': case '+': case '1':
101 >            *var = 1;
102 >            break;
103 >         case 'n': case 'N': case 'f': case 'F': case '-': case '0':
104 >            *var = 0;
105 >            break;
106 >         default:
107 >            return 0;
108 >      }
109 >      
110 >      return 1;
111 >   }
112 >
113     if (argc < 2) {
114        puts("Dump photon maps as RADIANCE scene description\n");
115 <      printf("Usage: %s [-r radscale1] [-n nspheres1] pmap1 "
116 <             "[-r radscale2] [-n nspheres2] pmap2 ...\n", argv [0]);
115 >      printf("Usage: %s "
116 >             "[-r radscale1] [-n nspheres1] [-f | -c rcol1 gcol1 bcol1] pmap1 "
117 >             "[-r radscale2] [-n nspheres2] [-f | -c rcol2 gcol2 bcol2] pmap2 "
118 >             "...\n", argv [0]);
119        return 1;
120     }
121    
# Line 103 | Line 133 | int main (int argc, char** argv)
133                    error(USER, "invalid number of spheres");
134                 break;
135                
136 +            case 'c':
137 +               if (fluxCol)
138 +                  error(USER, "-f and -c are mutually exclusive");
139 +              
140 +               if (badarg(argc - arg - 1, &argv [arg + 1], "fff"))
141 +                  error(USER, "invalid RGB colour");
142 +                                
143 +               for (j = 0; j < 3; j++)
144 +                  customCol [j] = atof(argv [++arg]);
145 +               break;
146 +              
147 +            case 'f':
148 +               if (intens(customCol) > 0)
149 +                  error(USER, "-f and -c are mutually exclusive");
150 +                  
151 +               if (!setBool(argv [arg], 2, &fluxCol))
152 +                  error(USER, "invalid option syntax at -f");
153 +               break;
154 +              
155              default:
156                 sprintf(errmsg, "unknown option %s", argv [arg]);
157                 error(USER, errmsg);
# Line 111 | Line 160 | int main (int argc, char** argv)
160          
161           continue;
162        }
163 <      
163 >
164        /* Dump photon map */
165        if (!(pmapFile = fopen(argv [arg], "rb"))) {
166           sprintf(errmsg, "can't open %s", argv [arg]);
167           error(SYSTEM, errmsg);
168        }
169 <        
169 >
170        /* Get format string */
171        strcpy(format, PMAP_FORMAT_GLOB);
172        if (checkheader(pmapFile, format, NULL) != 1) {
# Line 125 | Line 174 | int main (int argc, char** argv)
174                   argv [arg], format);
175           error(USER, errmsg);
176        }
177 <      
177 >
178        /* Identify photon map type from format string */
179        for (ptype = 0;
180 <           strcmp(pmapFormat [ptype], format) && ptype < NUM_PMAP_TYPES;
180 >           ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
181             ptype++);
182 <      
182 >
183        if (!validPmapType(ptype)) {
184           sprintf(errmsg, "file %s contains an unknown photon map type",
185                  argv [arg]);
# Line 138 | Line 187 | int main (int argc, char** argv)
187        }
188  
189        /* Get file format version and check for compatibility */
190 <      if (getint(sizeof(PMAP_FILEVER), pmapFile) != PMAP_FILEVER)
190 >      if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))      
191           error(USER, "incompatible photon map file format");
192 <        
192 >
193        /* Dump command line as comment */
194        fputs("# ", stdout);
195        printargs(argc, argv, stdout);
196        fputc('\n', stdout);
197 +
198 +      /* Dump common material def if constant for all photons,
199 +         i.e. independent of individual flux */
200 +      if (!fluxCol) {
201 +         if (intens(customCol) > 0)
202 +            printf(radDefs [ptype].mat,
203 +                   customCol [0], customCol [1], customCol [2]);
204 +         else
205 +            printf(radDefs [ptype].mat, colDefs [ptype][0],
206 +                   colDefs [ptype][1], colDefs [ptype][2]);
207 +         fputc('\n', stdout);
208 +      }
209        
210 <      /* Dump material def */  
211 <      fputs(radDefs [ptype].mat, stdout);
212 <      fputc('\n', stdout);
152 <      
153 <      /* Get number of photons (is this sizeof() hack portable?) */
154 <      numPhotons = getint(sizeof(((PhotonMap*)NULL) -> heapSize), pmapFile);
155 <      
210 >      /* Get number of photons */
211 >      pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
212 >
213        /* Skip avg photon flux */
214        for (j = 0; j < 3; j++)
215           getflt(pmapFile);
216 <      
216 >
217        /* Get distribution extent (min & max photon positions) */
218        for (j = 0; j < 3; j++) {
219 <         minPos [j] = getflt(pmapFile);
220 <         maxPos [j] = getflt(pmapFile);
219 >         pm.minPos [j] = getflt(pmapFile);
220 >         pm.maxPos [j] = getflt(pmapFile);
221        }
222        
223        /* Skip centre of gravity, and avg photon dist to it */
224        for (j = 0; j < 4; j++)
225           getflt(pmapFile);
226        
227 <      /* Sphere radius based on avg intersphere dist
228 <         (= sphere distrib density ^-1/3) */
229 <      vol = (maxPos [0] - minPos [0]) * (maxPos [1] - minPos [1]) *
230 <            (maxPos [2] - minPos [2]);
231 <      rad = radScale * RADCOEFF * pow(vol / numSpheres, 1./3.);
227 >      /* Sphere radius based on avg intersphere dist depending on
228 >         whether the distribution occupies a 1D line (!), a 2D plane,
229 >         or 3D volume (= sphere distrib density ^-1/d, where d is the
230 >         dimensionality of the distribution) */
231 >      for (j = 0, extent = 1.0, dim = 0; j < 3; j++) {
232 >         rad = pm.maxPos [j] - pm.minPos [j];
233 >        
234 >         if (rad > FTINY) {
235 >            dim++;
236 >            extent *= rad;
237 >         }
238 >      }
239 >
240 >      rad = radScale * RADCOEFF * pow(extent / numSpheres, 1./dim);
241        
242        /* Photon dump probability to satisfy target sphere count */
243 <      dumpRatio = numSpheres < numPhotons ? (float)numSpheres / numPhotons
244 <                                          : 1;
243 >      dumpRatio = numSpheres < pm.numPhotons
244 >                  ? (float)numSpheres / pm.numPhotons : 1;
245        
246 <      while (numPhotons-- > 0) {
247 <         /* Get photon position */            
246 >      /* Skip primary rays */
247 >      pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
248 >      while (pm.numPrimary-- > 0) {
249 >         /* Skip source index & incident dir */
250 >         getint(sizeof(pri.srcIdx), pmapFile);
251 > #ifdef PMAP_PRIMARYDIR
252 >         /* Skip primary incident dir */
253 >         getint(sizeof(pri.dir), pmapFile);        
254 > #endif
255 > #ifdef PMAP_PRIMARYPOS
256 >         /* Skip primary hitpoint */
257 >         for (j = 0; j < 3; j++)
258 >            getflt(pmapFile);
259 > #endif
260 >      }
261 >
262 > #ifdef PMAP_OOC
263 >      /* Open leaf file with filename derived from pmap, replace pmapFile
264 >       * (which is currently the node file) */
265 >      strncpy(leafFname, argv [arg], 1024);
266 >      strncat(leafFname, PMAP_OOC_LEAFSUFFIX, 1024);
267 >      fclose(pmapFile);
268 >      if (!(pmapFile = fopen(leafFname, "rb"))) {
269 >         sprintf(errmsg, "cannot open leaf file %s", leafFname);
270 >         error(SYSTEM, errmsg);
271 >      }
272 > #endif
273 >            
274 >      /* Load photons */      
275 >      while (pm.numPhotons-- > 0) {
276 > #ifdef PMAP_OOC
277 >         /* Get entire photon record from ooC octree leaf file
278 >            !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
279 >         if (!fread(&p, sizeof(p), 1, pmapFile)) {
280 >            sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
281 >            error(SYSTEM, errmsg);
282 >         }
283 > #else /* kd-tree */
284 >         /* Get photon position */
285           for (j = 0; j < 3; j++)
286              p.pos [j] = getflt(pmapFile);
287  
288 <         /* Dump photon probabilistically acc. to target sphere count */
186 <         if (frandom() <= dumpRatio) {
187 <            printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
188 <            fputc('\n', stdout);
189 <         }
190 <        
191 <         /* Skip photon normal and flux */
288 >         /* Get photon normal (currently not used) */
289           for (j = 0; j < 3; j++)
290 <            getint(sizeof(p.norm [j]), pmapFile);
194 <            
195 <         #ifdef PMAP_FLOAT_FLUX
196 <            for (j = 0; j < 3; j++)
197 <               getflt(pmapFile);
198 <         #else      
199 <            for (j = 0; j < 4; j++)
200 <               getint(1, pmapFile);
201 <         #endif
290 >            p.norm [j] = getint(1, pmapFile);
291  
292 +         /* Get photon flux */
293 +   #ifdef PMAP_FLOAT_FLUX
294 +         for (j = 0; j < 3; j++)
295 +            p.flux [j] = getflt(pmapFile);
296 +   #else
297 +         for (j = 0; j < 4; j++)
298 +            p.flux [j] = getint(1, pmapFile);
299 +   #endif
300 +
301           /* Skip primary ray index */
302           getint(sizeof(p.primary), pmapFile);
303  
304           /* Skip flags */
305           getint(sizeof(p.flags), pmapFile);
306 <        
307 <         if (feof(pmapFile)) {
306 > #endif
307 >
308 >         /* Dump photon probabilistically acc. to target sphere count */
309 >         if (frandom() <= dumpRatio) {
310 >            if (fluxCol) {
311 >               /* Dump individual material def per photon acc. to flux */
312 >               getPhotonFlux(&p, customCol);
313 >               printf(radDefs [ptype].mat,
314 >                      customCol [0], customCol [1], customCol [2]);
315 >               fputc('\n', stdout);
316 >            }
317 >            
318 >            printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
319 >            fputc('\n', stdout);
320 >         }
321 >              
322 >         if (ferror(pmapFile) || feof(pmapFile)) {
323              sprintf(errmsg, "error reading %s", argv [arg]);
324              error(USER, errmsg);
325           }
# Line 217 | Line 330 | int main (int argc, char** argv)
330        /* Reset defaults for next dump */
331        radScale = RADSCALE;
332        numSpheres = NSPHERES;
333 +      customCol [0] = customCol [1] = customCol [2] = 0;
334 +      fluxCol = 0;
335     }
336    
337     return 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines