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, 8 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pmapdump.c,v 2.16 2020/07/21 16:10:42 rschregle Exp $";
3 #endif
4
5 /*
6 ======================================================================
7 Dump photon maps as RADIANCE scene description or ASCII point list
8 to stdout
9
10 Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
11 (c) Fraunhofer Institute for Solar Energy Systems,
12 supported by the German Research Foundation (DFG)
13 under the FARESYS project.
14 (c) Lucerne University of Applied Sciences and Arts,
15 supported by the Swiss National Science Foundation (SNSF #147053).
16 (c) Tokyo University of Science,
17 supported by the JSPS KAKENHI Grant Number JP19KK0115.
18 ======================================================================
19
20 $Id: pmapdump.c,v 2.16 2020/07/21 16:10:42 rschregle Exp $
21 */
22
23
24
25 #include "pmap.h"
26 #include "pmapio.h"
27 #include "rtio.h"
28 #include "resolu.h"
29 #include "random.h"
30 #include "math.h"
31
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 /* 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
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 { "void glow mat.global\n0\n0\n4 %g %g %g 0\n",
51 "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
52 },
53 { "void glow mat.pglobal\n0\n0\n4 %g %g %g 0\n",
54 "mat.pglobal sphere obj.pglobal\n0\n0\n4 %g %g %g %g\n"
55 },
56 { "void glow mat.caustic\n0\n0\n4 %g %g %g 0\n",
57 "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
58 },
59 { "void glow mat.volume\n0\n0\n4 %g %g %g 0\n",
60 "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
61 },
62 { "void glow mat.direct\n0\n0\n4 %g %g %g 0\n",
63 "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
64 },
65 { "void glow mat.contrib\n0\n0\n4 %g %g %g 0\n",
66 "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
67 }
68 };
69
70
71 /* 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 {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 };
81
82
83 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 int main (int argc, char** argv)
104 {
105 char format [MAXFMTLEN];
106 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
107 unsigned arg, j, ptype, dim, fluxCol = 0, points = 0;
108 long numSpheres = NSPHERES;
109 COLOR col = {0, 0, 0};
110 FILE *pmapFile;
111 PhotonMap pm;
112 PhotonPrimary pri;
113 Photon p;
114 #ifdef PMAP_OOC
115 char leafFname [1024];
116 #endif
117
118 if (argc < 2) {
119 puts("Dump photon maps as RADIANCE scene description "
120 "or ASCII point list\n");
121 printf("Usage: %s "
122 "[-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 "...\n", argv [0]);
127 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 case 'a':
135 if (!setBool(argv [arg], 2, &points))
136 error(USER, "invalid option syntax at -a");
137 break;
138 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 error(USER, "invalid number of points/spheres");
146 break;
147
148 case 'c':
149 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 for (j = 0; j < 3; j++)
156 col [j] = atof(argv [++arg]);
157 break;
158
159 case 'f':
160 if (intens(col) > 0)
161 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 break;
166
167 default:
168 sprintf(errmsg, "unknown option %s", argv [arg]);
169 error(USER, errmsg);
170 return -1;
171 }
172
173 continue;
174 }
175
176 /* Open next photon map file */
177 if (!(pmapFile = fopen(argv [arg], "rb"))) {
178 sprintf(errmsg, "can't open %s", argv [arg]);
179 error(SYSTEM, errmsg);
180 }
181
182 /* 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
190 /* Identify photon map type from format string */
191 for (ptype = 0;
192 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
193 ptype++);
194
195 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 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
203 error(USER, "incompatible photon map file format");
204
205 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 if (!fluxCol) {
215 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 }
222
223 /* Get number of photons */
224 pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
225
226 /* Skip avg photon flux */
227 for (j = 0; j < 3; j++)
228 getflt(pmapFile);
229
230 /* Get distribution extent (min & max photon positions) */
231 for (j = 0; j < 3; j++) {
232 pm.minPos [j] = getflt(pmapFile);
233 pm.maxPos [j] = getflt(pmapFile);
234 }
235
236 /* Skip centre of gravity, and avg photon dist to it */
237 for (j = 0; j < 4; j++)
238 getflt(pmapFile);
239
240 /* 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
255 /* Photon dump probability to satisfy target sphere count */
256 dumpRatio = min(1, (float)numSpheres / pm.numPhotons);
257
258 /* Skip primary rays */
259 pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
260 while (pm.numPrimary-- > 0) {
261 /* Skip source index & incident dir */
262 getint(sizeof(pri.srcIdx), pmapFile);
263 #ifdef PMAP_PRIMARYDIR
264 /* Skip primary incident dir */
265 getint(sizeof(pri.dir), pmapFile);
266 #endif
267 #ifdef PMAP_PRIMARYPOS
268 /* Skip primary hitpoint */
269 for (j = 0; j < 3; j++)
270 getflt(pmapFile);
271 #endif
272 }
273
274 #ifdef PMAP_OOC
275 /* Open leaf file with filename derived from pmap, replace pmapFile
276 * (which is currently the node file) */
277 strncpy(leafFname, argv [arg], sizeof(leafFname) - 1);
278 strncat(leafFname, PMAP_OOC_LEAFSUFFIX, sizeof(leafFname) - 1);
279 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 /* Read photons */
287 while (pm.numPhotons-- > 0) {
288 #ifdef PMAP_OOC
289 /* Get entire photon record from ooC octree leaf file
290 !!! 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 #else /* kd-tree */
296 /* Get photon position */
297 for (j = 0; j < 3; j++)
298 p.pos [j] = getflt(pmapFile);
299
300 /* Get photon normal (currently not used) */
301 for (j = 0; j < 3; j++)
302 p.norm [j] = getint(1, pmapFile);
303
304 /* Get photon flux */
305 #ifdef PMAP_FLOAT_FLUX
306 for (j = 0; j < 3; j++)
307 p.flux [j] = getflt(pmapFile);
308 #else
309 for (j = 0; j < 4; j++)
310 p.flux [j] = getint(1, pmapFile);
311 #endif
312
313
314
315 /* Skip primary ray index */
316 getint(sizeof(p.primary), pmapFile);
317
318 /* Skip flags */
319 getint(sizeof(p.flags), pmapFile);
320 #endif
321
322 /* Dump photon probabilistically acc. to target sphere count */
323 if (frandom() <= dumpRatio) {
324 if (fluxCol) {
325 /* Get photon flux */
326 getPhotonFlux(&p, col);
327 /* Scale by dumpRatio for energy conservation */
328 scalecolor(col, 1.0 / dumpRatio);
329 }
330
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 fputc('\n', stdout);
340 }
341 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 }
345
346 if (ferror(pmapFile) || feof(pmapFile)) {
347 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 col [0] = col [1] = col [2] = 0;
358 fluxCol = points = 0;
359 }
360
361 return 0;
362 }