ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.10
Committed: Thu Feb 8 19:55:02 2018 UTC (6 years, 3 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.9: +8 -4 lines
Log Message:
Made photon primary incident dirs optional via PMAP_PRIMARYDIR, bumped PMAP_FILEVER

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pmapdump.c,v 2.9 2017/12/09 18:40:43 rschregle Exp $";
3 #endif
4
5 /*
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 ======================================================================
14
15 $Id: pmapdump.c,v 2.9 2017/12/09 18:40:43 rschregle Exp $
16 */
17
18
19
20 #include "pmapio.h"
21 #include "pmapparm.h"
22 #include "pmaptype.h"
23 #include "rtio.h"
24 #include "resolu.h"
25 #include "random.h"
26 #include "math.h"
27
28 #define PMAPDUMP_REC "$Revision: 2.9 $"
29
30
31 /* Defaults */
32 /* Sphere radius as fraction of avg. intersphere dist */
33 /* Relative scale for sphere radius (fudge factor) */
34 /* Number of spheres */
35 #define RADCOEFF 0.05
36 #define RADSCALE 1.0
37 #define NSPHERES 10000
38
39
40 /* RADIANCE material and object defs for each photon type */
41 typedef struct {
42 char *mat, *obj;
43 } RadianceDef;
44
45
46
47 /* Colour code is as follows: global = blue
48 precomp global = cyan
49 caustic = red
50 volume = green
51 direct = magenta
52 contrib = yellow */
53 const RadianceDef radDefs [] = {
54 { "void plastic mat.global\n0\n0\n5 0 0 1 0 0\n",
55 "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
56 },
57 { "void plastic mat.pglobal\n0\n0\n5 0 1 1 0 0\n",
58 "mat.pglobal sphere obj.global\n0\n0\n4 %g %g %g %g\n"
59 },
60 { "void plastic mat.caustic\n0\n0\n5 1 0 0 0 0\n",
61 "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
62 },
63 { "void plastic mat.volume\n0\n0\n5 0 1 0 0 0\n",
64 "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
65 },
66 { "void plastic mat.direct\n0\n0\n5 1 0 1 0 0\n",
67 "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
68 },
69 { "void plastic mat.contrib\n0\n0\n5 1 1 0 0 0\n",
70 "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
71 }
72 };
73
74
75
76 int main (int argc, char** argv)
77 {
78 char format [128];
79 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
80 unsigned arg, j, ptype, dim;
81 long numSpheres = NSPHERES;
82 FILE *pmapFile;
83 PhotonMap pm;
84 PhotonPrimary pri;
85 Photon p;
86 #ifdef PMAP_OOC
87 char leafFname [1024];
88 #endif
89
90 if (argc < 2) {
91 puts("Dump photon maps as RADIANCE scene description\n");
92 printf("Usage: %s [-r radscale1] [-n nspheres1] pmap1 "
93 "[-r radscale2] [-n nspheres2] pmap2 ...\n", argv [0]);
94 return 1;
95 }
96
97 for (arg = 1; arg < argc; arg++) {
98 /* Parse options */
99 if (argv [arg][0] == '-') {
100 switch (argv [arg][1]) {
101 case 'r':
102 if ((radScale = atof(argv [++arg])) <= 0)
103 error(USER, "invalid radius scale");
104 break;
105
106 case 'n':
107 if ((numSpheres = parseMultiplier(argv [++arg])) <= 0)
108 error(USER, "invalid number of spheres");
109 break;
110
111 default:
112 sprintf(errmsg, "unknown option %s", argv [arg]);
113 error(USER, errmsg);
114 return -1;
115 }
116
117 continue;
118 }
119
120 /* Dump photon map */
121 if (!(pmapFile = fopen(argv [arg], "rb"))) {
122 sprintf(errmsg, "can't open %s", argv [arg]);
123 error(SYSTEM, errmsg);
124 }
125
126 /* Get format string */
127 strcpy(format, PMAP_FORMAT_GLOB);
128 if (checkheader(pmapFile, format, NULL) != 1) {
129 sprintf(errmsg, "photon map file %s has unknown format %s",
130 argv [arg], format);
131 error(USER, errmsg);
132 }
133
134 /* Identify photon map type from format string */
135 for (ptype = 0;
136 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
137 ptype++);
138
139 if (!validPmapType(ptype)) {
140 sprintf(errmsg, "file %s contains an unknown photon map type",
141 argv [arg]);
142 error(USER, errmsg);
143 }
144
145 /* Get file format version and check for compatibility */
146 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
147 error(USER, "incompatible photon map file format");
148
149 /* Dump command line as comment */
150 fputs("# ", stdout);
151 printargs(argc, argv, stdout);
152 fputc('\n', stdout);
153
154 /* Dump material def */
155 fputs(radDefs [ptype].mat, stdout);
156 fputc('\n', stdout);
157
158 /* Get number of photons */
159 pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
160
161 /* Skip avg photon flux */
162 for (j = 0; j < 3; j++)
163 getflt(pmapFile);
164
165 /* Get distribution extent (min & max photon positions) */
166 for (j = 0; j < 3; j++) {
167 pm.minPos [j] = getflt(pmapFile);
168 pm.maxPos [j] = getflt(pmapFile);
169 }
170
171 /* Skip centre of gravity, and avg photon dist to it */
172 for (j = 0; j < 4; j++)
173 getflt(pmapFile);
174
175 /* Sphere radius based on avg intersphere dist depending on
176 whether the distribution occupies a 1D line (!), a 2D plane,
177 or 3D volume (= sphere distrib density ^-1/d, where d is the
178 dimensionality of the distribution) */
179 for (j = 0, extent = 1.0, dim = 0; j < 3; j++) {
180 rad = pm.maxPos [j] - pm.minPos [j];
181
182 if (rad > FTINY) {
183 dim++;
184 extent *= rad;
185 }
186 }
187
188 rad = radScale * RADCOEFF * pow(extent / numSpheres, 1./dim);
189
190 /* Photon dump probability to satisfy target sphere count */
191 dumpRatio = numSpheres < pm.numPhotons
192 ? (float)numSpheres / pm.numPhotons : 1;
193
194 /* Skip primary rays */
195 pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
196 while (pm.numPrimary-- > 0) {
197 /* Skip source index & incident dir */
198 getint(sizeof(pri.srcIdx), pmapFile);
199 #ifdef PMAP_PRIMARYDIR
200 /* Skip primary incident dir */
201 getint(sizeof(pri.dir), pmapFile);
202 #endif
203 #ifdef PMAP_PRIMARYPOS
204 /* Skip primary hitpoint */
205 for (j = 0; j < 3; j++)
206 getflt(pmapFile);
207 #endif
208 }
209
210 #ifdef PMAP_OOC
211 /* Open leaf file with filename derived from pmap, replace pmapFile
212 * (which is currently the node file) */
213 strncpy(leafFname, argv [arg], 1024);
214 strncat(leafFname, PMAP_OOC_LEAFSUFFIX, 1024);
215 fclose(pmapFile);
216 if (!(pmapFile = fopen(leafFname, "rb"))) {
217 sprintf(errmsg, "cannot open leaf file %s", leafFname);
218 error(SYSTEM, errmsg);
219 }
220 #endif
221
222 /* Load photons */
223 while (pm.numPhotons-- > 0) {
224 #ifdef PMAP_OOC
225 /* Get entire photon record
226 !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
227 if (!fread(&p, sizeof(p), 1, pmapFile)) {
228 sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
229 error(SYSTEM, errmsg);
230 }
231 #else
232 /* Get photon position */
233 for (j = 0; j < 3; j++)
234 p.pos [j] = getflt(pmapFile);
235 #endif
236 /* Dump photon probabilistically acc. to target sphere count */
237 if (frandom() <= dumpRatio) {
238 printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
239 fputc('\n', stdout);
240 }
241
242 #ifndef PMAP_OOC
243 /* Skip photon normal and flux */
244 for (j = 0; j < 3; j++)
245 getint(sizeof(p.norm [j]), pmapFile);
246
247 #ifdef PMAP_FLOAT_FLUX
248 for (j = 0; j < 3; j++)
249 getflt(pmapFile);
250 #else
251 for (j = 0; j < 4; j++)
252 getint(1, pmapFile);
253 #endif
254
255 /* Skip primary ray index */
256 getint(sizeof(p.primary), pmapFile);
257
258 /* Skip flags */
259 getint(sizeof(p.flags), pmapFile);
260 #endif
261
262 if (ferror(pmapFile) || feof(pmapFile)) {
263 sprintf(errmsg, "error reading %s", argv [arg]);
264 error(USER, errmsg);
265 }
266 }
267
268 fclose(pmapFile);
269
270 /* Reset defaults for next dump */
271 radScale = RADSCALE;
272 numSpheres = NSPHERES;
273 }
274
275 return 0;
276 }