ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.12
Committed: Wed Nov 21 19:30:59 2018 UTC (6 years, 5 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.11: +37 -20 lines
Log Message:
Added -c option to specify custom sphere colours

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pmapdump.c,v 2.11 2018/08/02 18:33:49 greg 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.11 2018/08/02 18:33:49 greg 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.11 $"
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 const RadianceDef radDefs [] = {
47 { "void plastic mat.global\n0\n0\n5 %f %f %f 0 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 %f %f %f 0 0\n",
51 "mat.pglobal sphere obj.global\n0\n0\n4 %g %g %g %g\n"
52 },
53 { "void plastic mat.caustic\n0\n0\n5 %f %f %f 0 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 %f %f %f 0 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 %f %f %f 0 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 %f %f %f 0 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, 0, 1}, {0, 1, 1}, {1, 0, 0}, {0, 1, 0}, {1, 0, 1}, {1, 1, 0}
75 };
76
77
78 int main (int argc, char** argv)
79 {
80 char format [MAXFMTLEN];
81 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
82 unsigned arg, j, ptype, dim;
83 long numSpheres = NSPHERES;
84 COLOR customCol = {0, 0, 0};
85 FILE *pmapFile;
86 PhotonMap pm;
87 PhotonPrimary pri;
88 Photon p;
89 #ifdef PMAP_OOC
90 char leafFname [1024];
91 #endif
92
93 if (argc < 2) {
94 puts("Dump photon maps as RADIANCE scene description\n");
95 printf("Usage: %s "
96 "[-r radscale1] [-n nspheres1] [-c rcol1 gcol1 bcol1] pmap1 "
97 "[-r radscale2] [-n nspheres2] [-c rcol2 gcol2 bcol2] pmap2 "
98 "...\n", argv [0]);
99 return 1;
100 }
101
102 for (arg = 1; arg < argc; arg++) {
103 /* Parse options */
104 if (argv [arg][0] == '-') {
105 switch (argv [arg][1]) {
106 case 'r':
107 if ((radScale = atof(argv [++arg])) <= 0)
108 error(USER, "invalid radius scale");
109 break;
110
111 case 'n':
112 if ((numSpheres = parseMultiplier(argv [++arg])) <= 0)
113 error(USER, "invalid number of spheres");
114 break;
115
116 case 'c':
117 for (j = 0; j < 3; j++)
118 if ((customCol [j] = atof(argv [++arg])) <= 0)
119 error(USER, "invalid RGB colour");
120 break;
121
122 default:
123 sprintf(errmsg, "unknown option %s", argv [arg]);
124 error(USER, errmsg);
125 return -1;
126 }
127
128 continue;
129 }
130
131 /* Dump photon map */
132 if (!(pmapFile = fopen(argv [arg], "rb"))) {
133 sprintf(errmsg, "can't open %s", argv [arg]);
134 error(SYSTEM, errmsg);
135 }
136
137 /* Get format string */
138 strcpy(format, PMAP_FORMAT_GLOB);
139 if (checkheader(pmapFile, format, NULL) != 1) {
140 sprintf(errmsg, "photon map file %s has unknown format %s",
141 argv [arg], format);
142 error(USER, errmsg);
143 }
144
145 /* Identify photon map type from format string */
146 for (ptype = 0;
147 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
148 ptype++);
149
150 if (!validPmapType(ptype)) {
151 sprintf(errmsg, "file %s contains an unknown photon map type",
152 argv [arg]);
153 error(USER, errmsg);
154 }
155
156 /* Get file format version and check for compatibility */
157 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
158 error(USER, "incompatible photon map file format");
159
160 /* Dump command line as comment */
161 fputs("# ", stdout);
162 printargs(argc, argv, stdout);
163 fputc('\n', stdout);
164
165 /* Dump material def */
166 if (intens(customCol) > 0)
167 printf(radDefs [ptype].mat,
168 customCol [0], customCol [1], customCol [2]);
169 else
170 printf(radDefs [ptype].mat,
171 colDefs [ptype][0], colDefs [ptype][1], colDefs [ptype][2]);
172 fputc('\n', stdout);
173
174 /* Get number of photons */
175 pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
176
177 /* Skip avg photon flux */
178 for (j = 0; j < 3; j++)
179 getflt(pmapFile);
180
181 /* Get distribution extent (min & max photon positions) */
182 for (j = 0; j < 3; j++) {
183 pm.minPos [j] = getflt(pmapFile);
184 pm.maxPos [j] = getflt(pmapFile);
185 }
186
187 /* Skip centre of gravity, and avg photon dist to it */
188 for (j = 0; j < 4; j++)
189 getflt(pmapFile);
190
191 /* Sphere radius based on avg intersphere dist depending on
192 whether the distribution occupies a 1D line (!), a 2D plane,
193 or 3D volume (= sphere distrib density ^-1/d, where d is the
194 dimensionality of the distribution) */
195 for (j = 0, extent = 1.0, dim = 0; j < 3; j++) {
196 rad = pm.maxPos [j] - pm.minPos [j];
197
198 if (rad > FTINY) {
199 dim++;
200 extent *= rad;
201 }
202 }
203
204 rad = radScale * RADCOEFF * pow(extent / numSpheres, 1./dim);
205
206 /* Photon dump probability to satisfy target sphere count */
207 dumpRatio = numSpheres < pm.numPhotons
208 ? (float)numSpheres / pm.numPhotons : 1;
209
210 /* Skip primary rays */
211 pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
212 while (pm.numPrimary-- > 0) {
213 /* Skip source index & incident dir */
214 getint(sizeof(pri.srcIdx), pmapFile);
215 #ifdef PMAP_PRIMARYDIR
216 /* Skip primary incident dir */
217 getint(sizeof(pri.dir), pmapFile);
218 #endif
219 #ifdef PMAP_PRIMARYPOS
220 /* Skip primary hitpoint */
221 for (j = 0; j < 3; j++)
222 getflt(pmapFile);
223 #endif
224 }
225
226 #ifdef PMAP_OOC
227 /* Open leaf file with filename derived from pmap, replace pmapFile
228 * (which is currently the node file) */
229 strncpy(leafFname, argv [arg], 1024);
230 strncat(leafFname, PMAP_OOC_LEAFSUFFIX, 1024);
231 fclose(pmapFile);
232 if (!(pmapFile = fopen(leafFname, "rb"))) {
233 sprintf(errmsg, "cannot open leaf file %s", leafFname);
234 error(SYSTEM, errmsg);
235 }
236 #endif
237
238 /* Load photons */
239 while (pm.numPhotons-- > 0) {
240 #ifdef PMAP_OOC
241 /* Get entire photon record
242 !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
243 if (!fread(&p, sizeof(p), 1, pmapFile)) {
244 sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
245 error(SYSTEM, errmsg);
246 }
247 #else
248 /* Get photon position */
249 for (j = 0; j < 3; j++)
250 p.pos [j] = getflt(pmapFile);
251 #endif
252 /* Dump photon probabilistically acc. to target sphere count */
253 if (frandom() <= dumpRatio) {
254 printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
255 fputc('\n', stdout);
256 }
257
258 #ifndef PMAP_OOC
259 /* Skip photon normal and flux */
260 for (j = 0; j < 3; j++)
261 getint(sizeof(p.norm [j]), pmapFile);
262
263 #ifdef PMAP_FLOAT_FLUX
264 for (j = 0; j < 3; j++)
265 getflt(pmapFile);
266 #else
267 for (j = 0; j < 4; j++)
268 getint(1, pmapFile);
269 #endif
270
271 /* Skip primary ray index */
272 getint(sizeof(p.primary), pmapFile);
273
274 /* Skip flags */
275 getint(sizeof(p.flags), pmapFile);
276 #endif
277
278 if (ferror(pmapFile) || feof(pmapFile)) {
279 sprintf(errmsg, "error reading %s", argv [arg]);
280 error(USER, errmsg);
281 }
282 }
283
284 fclose(pmapFile);
285
286 /* Reset defaults for next dump */
287 radScale = RADSCALE;
288 numSpheres = NSPHERES;
289 customCol [0] = customCol [1] = customCol [2] = 0;
290 }
291
292 return 0;
293 }