ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.17
Committed: Fri Aug 7 01:21:13 2020 UTC (3 years, 9 months ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.16: +5 -7 lines
Log Message:
feat(mkpmap): Extended -apo option to reorient photon ports.

File Contents

# User Rev Content
1 greg 2.4 #ifndef lint
2 rschregle 2.17 static const char RCSid[] = "$Id: pmapdump.c,v 2.16 2020/07/21 16:10:42 rschregle Exp $";
3 greg 2.4 #endif
4 rschregle 2.7
5 greg 2.1 /*
6 rschregle 2.7 ======================================================================
7 rschregle 2.14 Dump photon maps as RADIANCE scene description or ASCII point list
8     to stdout
9 greg 2.1
10     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
11     (c) Fraunhofer Institute for Solar Energy Systems,
12 rschregle 2.16 supported by the German Research Foundation (DFG)
13 rschregle 2.17 under the FARESYS project.
14 rschregle 2.3 (c) Lucerne University of Applied Sciences and Arts,
15 rschregle 2.17 supported by the Swiss National Science Foundation (SNSF #147053).
16 rschregle 2.16 (c) Tokyo University of Science,
17 rschregle 2.17 supported by the JSPS KAKENHI Grant Number JP19KK0115.
18 rschregle 2.7 ======================================================================
19 greg 2.1
20 rschregle 2.17 $Id: pmapdump.c,v 2.16 2020/07/21 16:10:42 rschregle Exp $
21 greg 2.1 */
22    
23    
24    
25 rschregle 2.14 #include "pmap.h"
26 greg 2.1 #include "pmapio.h"
27     #include "rtio.h"
28     #include "resolu.h"
29     #include "random.h"
30 greg 2.2 #include "math.h"
31 greg 2.1
32    
33     /* Defaults */
34     /* Sphere radius as fraction of avg. intersphere dist */
35     /* Relative scale for sphere radius (fudge factor) */
36     /* Number of spheres */
37     #define RADCOEFF 0.05
38     #define RADSCALE 1.0
39     #define NSPHERES 10000
40    
41 rschregle 2.14 /* Format for optional ASCII output as XYZ RGB points */
42     #define POINTFMT "%g\t%g\t%g\t%g\t%g\t%g\n"
43 greg 2.1
44     /* RADIANCE material and object defs for each photon type */
45     typedef struct {
46     char *mat, *obj;
47     } RadianceDef;
48    
49     const RadianceDef radDefs [] = {
50 rschregle 2.14 { "void glow mat.global\n0\n0\n4 %g %g %g 0\n",
51 greg 2.1 "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
52     },
53 rschregle 2.14 { "void glow mat.pglobal\n0\n0\n4 %g %g %g 0\n",
54 rschregle 2.13 "mat.pglobal sphere obj.pglobal\n0\n0\n4 %g %g %g %g\n"
55 greg 2.1 },
56 rschregle 2.14 { "void glow mat.caustic\n0\n0\n4 %g %g %g 0\n",
57 greg 2.1 "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
58     },
59 rschregle 2.14 { "void glow mat.volume\n0\n0\n4 %g %g %g 0\n",
60 greg 2.1 "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
61     },
62 rschregle 2.14 { "void glow mat.direct\n0\n0\n4 %g %g %g 0\n",
63 greg 2.1 "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
64     },
65 rschregle 2.14 { "void glow mat.contrib\n0\n0\n4 %g %g %g 0\n",
66 greg 2.1 "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
67     }
68     };
69    
70 rschregle 2.14
71 rschregle 2.12 /* Default colour codes are as follows: global = blue
72     precomp global = cyan
73     caustic = red
74     volume = green
75     direct = magenta
76     contrib = yellow */
77     const COLOR colDefs [] = {
78 rschregle 2.13 {0.25, 0.25, 2}, {0.1, 1, 1}, {1, 0.1, 0.1},
79     {0.1, 1, 0.1}, {1, 0.1, 1}, {1, 1, 0.1}
80 rschregle 2.12 };
81 greg 2.1
82    
83 rschregle 2.14 static int setBool(char *str, unsigned pos, unsigned *var)
84     {
85     switch ((str) [pos]) {
86     case '\0':
87     *var = !*var;
88     break;
89     case 'y': case 'Y': case 't': case 'T': case '+': case '1':
90     *var = 1;
91     break;
92     case 'n': case 'N': case 'f': case 'F': case '-': case '0':
93     *var = 0;
94     break;
95     default:
96     return 0;
97     }
98    
99     return 1;
100     }
101    
102    
103 greg 2.1 int main (int argc, char** argv)
104     {
105 greg 2.11 char format [MAXFMTLEN];
106 rschregle 2.9 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
107 rschregle 2.14 unsigned arg, j, ptype, dim, fluxCol = 0, points = 0;
108 rschregle 2.7 long numSpheres = NSPHERES;
109 rschregle 2.14 COLOR col = {0, 0, 0};
110 rschregle 2.7 FILE *pmapFile;
111     PhotonMap pm;
112     PhotonPrimary pri;
113     Photon p;
114     #ifdef PMAP_OOC
115     char leafFname [1024];
116     #endif
117 rschregle 2.13
118 greg 2.1 if (argc < 2) {
119 rschregle 2.14 puts("Dump photon maps as RADIANCE scene description "
120     "or ASCII point list\n");
121 rschregle 2.12 printf("Usage: %s "
122 rschregle 2.14 "[-a] [-r radscale1] [-n num1] "
123     "[-f | -c rcol1 gcol1 bcol1] pmap1 "
124     "[-a] [-r radscale2] [-n num2] "
125     "[-f | -c rcol2 gcol2 bcol2] pmap2 "
126 rschregle 2.12 "...\n", argv [0]);
127 greg 2.1 return 1;
128     }
129    
130     for (arg = 1; arg < argc; arg++) {
131     /* Parse options */
132     if (argv [arg][0] == '-') {
133     switch (argv [arg][1]) {
134 rschregle 2.14 case 'a':
135     if (!setBool(argv [arg], 2, &points))
136     error(USER, "invalid option syntax at -a");
137     break;
138 greg 2.1 case 'r':
139     if ((radScale = atof(argv [++arg])) <= 0)
140     error(USER, "invalid radius scale");
141     break;
142    
143     case 'n':
144     if ((numSpheres = parseMultiplier(argv [++arg])) <= 0)
145 rschregle 2.14 error(USER, "invalid number of points/spheres");
146 greg 2.1 break;
147    
148 rschregle 2.12 case 'c':
149 rschregle 2.13 if (fluxCol)
150     error(USER, "-f and -c are mutually exclusive");
151    
152     if (badarg(argc - arg - 1, &argv [arg + 1], "fff"))
153     error(USER, "invalid RGB colour");
154    
155 rschregle 2.12 for (j = 0; j < 3; j++)
156 rschregle 2.14 col [j] = atof(argv [++arg]);
157 rschregle 2.13 break;
158    
159     case 'f':
160 rschregle 2.14 if (intens(col) > 0)
161 rschregle 2.13 error(USER, "-f and -c are mutually exclusive");
162    
163     if (!setBool(argv [arg], 2, &fluxCol))
164     error(USER, "invalid option syntax at -f");
165 rschregle 2.12 break;
166    
167 greg 2.1 default:
168     sprintf(errmsg, "unknown option %s", argv [arg]);
169     error(USER, errmsg);
170     return -1;
171     }
172    
173     continue;
174     }
175 rschregle 2.13
176 rschregle 2.14 /* Open next photon map file */
177 greg 2.1 if (!(pmapFile = fopen(argv [arg], "rb"))) {
178     sprintf(errmsg, "can't open %s", argv [arg]);
179     error(SYSTEM, errmsg);
180     }
181 rschregle 2.13
182 greg 2.1 /* Get format string */
183     strcpy(format, PMAP_FORMAT_GLOB);
184     if (checkheader(pmapFile, format, NULL) != 1) {
185     sprintf(errmsg, "photon map file %s has unknown format %s",
186     argv [arg], format);
187     error(USER, errmsg);
188     }
189 rschregle 2.13
190 greg 2.1 /* Identify photon map type from format string */
191     for (ptype = 0;
192 rschregle 2.6 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
193 greg 2.1 ptype++);
194 rschregle 2.13
195 greg 2.1 if (!validPmapType(ptype)) {
196     sprintf(errmsg, "file %s contains an unknown photon map type",
197     argv [arg]);
198     error(USER, errmsg);
199     }
200    
201     /* Get file format version and check for compatibility */
202 rschregle 2.7 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
203 greg 2.1 error(USER, "incompatible photon map file format");
204 rschregle 2.13
205 rschregle 2.14 if (!points) {
206     /* Dump command line as comment */
207     fputs("# ", stdout);
208     printargs(argc, argv, stdout);
209     fputc('\n', stdout);
210     }
211    
212     /* Set point/sphere colour if independent of photon flux,
213     output RADIANCE material def if required */
214 rschregle 2.13 if (!fluxCol) {
215 rschregle 2.14 if (intens(col) <= 0)
216     copycolor(col, colDefs [ptype]);
217     if (!points) {
218     printf(radDefs [ptype].mat, col [0], col [1], col [2]);
219     fputc('\n', stdout);
220     }
221 rschregle 2.13 }
222 greg 2.1
223 rschregle 2.7 /* Get number of photons */
224     pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
225 rschregle 2.13
226 greg 2.1 /* Skip avg photon flux */
227     for (j = 0; j < 3; j++)
228     getflt(pmapFile);
229 rschregle 2.13
230 greg 2.1 /* Get distribution extent (min & max photon positions) */
231     for (j = 0; j < 3; j++) {
232 rschregle 2.7 pm.minPos [j] = getflt(pmapFile);
233     pm.maxPos [j] = getflt(pmapFile);
234 greg 2.1 }
235    
236     /* Skip centre of gravity, and avg photon dist to it */
237     for (j = 0; j < 4; j++)
238     getflt(pmapFile);
239    
240 rschregle 2.9 /* Sphere radius based on avg intersphere dist depending on
241     whether the distribution occupies a 1D line (!), a 2D plane,
242     or 3D volume (= sphere distrib density ^-1/d, where d is the
243     dimensionality of the distribution) */
244     for (j = 0, extent = 1.0, dim = 0; j < 3; j++) {
245     rad = pm.maxPos [j] - pm.minPos [j];
246    
247     if (rad > FTINY) {
248     dim++;
249     extent *= rad;
250     }
251     }
252    
253     rad = radScale * RADCOEFF * pow(extent / numSpheres, 1./dim);
254 greg 2.1
255     /* Photon dump probability to satisfy target sphere count */
256 rschregle 2.14 dumpRatio = min(1, (float)numSpheres / pm.numPhotons);
257 greg 2.1
258 rschregle 2.7 /* Skip primary rays */
259     pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
260     while (pm.numPrimary-- > 0) {
261 rschregle 2.8 /* Skip source index & incident dir */
262 rschregle 2.10 getint(sizeof(pri.srcIdx), pmapFile);
263     #ifdef PMAP_PRIMARYDIR
264     /* Skip primary incident dir */
265     getint(sizeof(pri.dir), pmapFile);
266 rschregle 2.13 #endif
267     #ifdef PMAP_PRIMARYPOS
268 rschregle 2.8 /* Skip primary hitpoint */
269 rschregle 2.7 for (j = 0; j < 3; j++)
270     getflt(pmapFile);
271 rschregle 2.8 #endif
272 rschregle 2.7 }
273    
274     #ifdef PMAP_OOC
275     /* Open leaf file with filename derived from pmap, replace pmapFile
276     * (which is currently the node file) */
277 rschregle 2.16 strncpy(leafFname, argv [arg], sizeof(leafFname) - 1);
278     strncat(leafFname, PMAP_OOC_LEAFSUFFIX, sizeof(leafFname) - 1);
279 rschregle 2.7 fclose(pmapFile);
280     if (!(pmapFile = fopen(leafFname, "rb"))) {
281     sprintf(errmsg, "cannot open leaf file %s", leafFname);
282     error(SYSTEM, errmsg);
283     }
284     #endif
285    
286 rschregle 2.14 /* Read photons */
287 rschregle 2.7 while (pm.numPhotons-- > 0) {
288     #ifdef PMAP_OOC
289 rschregle 2.13 /* Get entire photon record from ooC octree leaf file
290 rschregle 2.7 !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
291     if (!fread(&p, sizeof(p), 1, pmapFile)) {
292     sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
293     error(SYSTEM, errmsg);
294     }
295 rschregle 2.13 #else /* kd-tree */
296     /* Get photon position */
297 greg 2.1 for (j = 0; j < 3; j++)
298     p.pos [j] = getflt(pmapFile);
299 rschregle 2.13
300     /* Get photon normal (currently not used) */
301 greg 2.1 for (j = 0; j < 3; j++)
302 rschregle 2.13 p.norm [j] = getint(1, pmapFile);
303    
304     /* Get photon flux */
305     #ifdef PMAP_FLOAT_FLUX
306 rschregle 2.7 for (j = 0; j < 3; j++)
307 rschregle 2.13 p.flux [j] = getflt(pmapFile);
308     #else
309 rschregle 2.7 for (j = 0; j < 4; j++)
310 rschregle 2.13 p.flux [j] = getint(1, pmapFile);
311     #endif
312 rschregle 2.15
313    
314 greg 2.1
315     /* Skip primary ray index */
316     getint(sizeof(p.primary), pmapFile);
317    
318     /* Skip flags */
319     getint(sizeof(p.flags), pmapFile);
320 rschregle 2.7 #endif
321 rschregle 2.13
322     /* Dump photon probabilistically acc. to target sphere count */
323     if (frandom() <= dumpRatio) {
324 rschregle 2.15 if (fluxCol) {
325 rschregle 2.14 /* Get photon flux */
326     getPhotonFlux(&p, col);
327 rschregle 2.15 /* Scale by dumpRatio for energy conservation */
328     scalecolor(col, 1.0 / dumpRatio);
329     }
330 rschregle 2.14
331     if (!points) {
332     if (fluxCol) {
333     /* Dump material def if variable (depends on flux) */
334     printf(radDefs [ptype].mat, col [0], col [1], col [2]);
335     fputc('\n', stdout);
336     }
337     printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2],
338     rad);
339 rschregle 2.13 fputc('\n', stdout);
340     }
341 rschregle 2.14 else /* Dump as XYZ RGB point */
342     printf(POINTFMT, p.pos [0], p.pos [1], p.pos [2],
343     col [0], col [1] ,col [2]);
344 rschregle 2.13 }
345 rschregle 2.14
346 rschregle 2.7 if (ferror(pmapFile) || feof(pmapFile)) {
347 greg 2.1 sprintf(errmsg, "error reading %s", argv [arg]);
348     error(USER, errmsg);
349     }
350     }
351    
352     fclose(pmapFile);
353    
354     /* Reset defaults for next dump */
355     radScale = RADSCALE;
356     numSpheres = NSPHERES;
357 rschregle 2.14 col [0] = col [1] = col [2] = 0;
358     fluxCol = points = 0;
359 greg 2.1 }
360    
361     return 0;
362     }