ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.6
Committed: Thu Feb 4 19:39:10 2016 UTC (8 years, 3 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.5: +3 -3 lines
Log Message:
Fixed SEGFAULTs when pmapdump fails to identify newer pmap formats

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: pmapdump.c,v 4.19 2016/02/04 19:34:44 taschreg Exp taschreg $";
3 #endif
4 /*
5 ==================================================================
6 Dump photon maps as RADIANCE scene description to stdout
7
8 Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
9 (c) Fraunhofer Institute for Solar Energy Systems,
10 (c) Lucerne University of Applied Sciences and Arts,
11 supported by the Swiss National Science Foundation (SNSF, #147053)
12 ==================================================================
13
14 */
15
16
17
18 #include "pmapio.h"
19 #include "pmapparm.h"
20 #include "pmaptype.h"
21 #include "rtio.h"
22 #include "resolu.h"
23 #include "random.h"
24 #include "math.h"
25
26
27 /* Defaults */
28 /* Sphere radius as fraction of avg. intersphere dist */
29 /* Relative scale for sphere radius (fudge factor) */
30 /* Number of spheres */
31 #define RADCOEFF 0.05
32 #define RADSCALE 1.0
33 #define NSPHERES 10000
34
35
36 /* RADIANCE material and object defs for each photon type */
37 typedef struct {
38 char *mat, *obj;
39 } RadianceDef;
40
41
42 static char header [] = "$Revision: 4.19 $";
43
44
45 /* Colour code is as follows: global = blue
46 precomp global = cyan
47 caustic = red
48 volume = green
49 direct = magenta
50 contrib = yellow */
51 const RadianceDef radDefs [] = {
52 { "void plastic mat.global\n0\n0\n5 0 0 1 0 0\n",
53 "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
54 },
55 { "void plastic mat.pglobal\n0\n0\n5 0 1 1 0 0\n",
56 "mat.pglobal sphere obj.global\n0\n0\n4 %g %g %g %g\n"
57 },
58 { "void plastic mat.caustic\n0\n0\n5 1 0 0 0 0\n",
59 "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
60 },
61 { "void plastic mat.volume\n0\n0\n5 0 1 0 0 0\n",
62 "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
63 },
64 { "void plastic mat.direct\n0\n0\n5 1 0 1 0 0\n",
65 "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
66 },
67 { "void plastic mat.contrib\n0\n0\n5 1 1 0 0 0\n",
68 "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
69 }
70 };
71
72
73
74 int main (int argc, char** argv)
75 {
76 char format [128];
77 RREAL rad, radScale = RADSCALE, vol, dumpRatio;
78 FVECT minPos, maxPos;
79 unsigned arg, j, ptype;
80 long numPhotons, numSpheres = NSPHERES;
81 FILE *pmapFile;
82 Photon p;
83
84 if (argc < 2) {
85 puts("Dump photon maps as RADIANCE scene description\n");
86 printf("Usage: %s [-r radscale1] [-n nspheres1] pmap1 "
87 "[-r radscale2] [-n nspheres2] pmap2 ...\n", argv [0]);
88 return 1;
89 }
90
91 for (arg = 1; arg < argc; arg++) {
92 /* Parse options */
93 if (argv [arg][0] == '-') {
94 switch (argv [arg][1]) {
95 case 'r':
96 if ((radScale = atof(argv [++arg])) <= 0)
97 error(USER, "invalid radius scale");
98 break;
99
100 case 'n':
101 if ((numSpheres = parseMultiplier(argv [++arg])) <= 0)
102 error(USER, "invalid number of spheres");
103 break;
104
105 default:
106 sprintf(errmsg, "unknown option %s", argv [arg]);
107 error(USER, errmsg);
108 return -1;
109 }
110
111 continue;
112 }
113
114 /* Dump photon map */
115 if (!(pmapFile = fopen(argv [arg], "rb"))) {
116 sprintf(errmsg, "can't open %s", argv [arg]);
117 error(SYSTEM, errmsg);
118 }
119
120 /* Get format string */
121 strcpy(format, PMAP_FORMAT_GLOB);
122 if (checkheader(pmapFile, format, NULL) != 1) {
123 sprintf(errmsg, "photon map file %s has unknown format %s",
124 argv [arg], format);
125 error(USER, errmsg);
126 }
127
128 /* Identify photon map type from format string */
129 for (ptype = 0;
130 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
131 ptype++);
132
133 if (!validPmapType(ptype)) {
134 sprintf(errmsg, "file %s contains an unknown photon map type",
135 argv [arg]);
136 error(USER, errmsg);
137 }
138
139 /* Get file format version and check for compatibility */
140 if (getint(sizeof(PMAP_FILEVER), pmapFile) != PMAP_FILEVER)
141 error(USER, "incompatible photon map file format");
142
143 /* Dump command line as comment */
144 fputs("# ", stdout);
145 printargs(argc, argv, stdout);
146 fputc('\n', stdout);
147
148 /* Dump material def */
149 fputs(radDefs [ptype].mat, stdout);
150 fputc('\n', stdout);
151
152 /* Get number of photons (is this sizeof() hack portable?) */
153 numPhotons = getint(sizeof(((PhotonMap*)NULL) -> heapSize), pmapFile);
154
155 /* Skip avg photon flux */
156 for (j = 0; j < 3; j++)
157 getflt(pmapFile);
158
159 /* Get distribution extent (min & max photon positions) */
160 for (j = 0; j < 3; j++) {
161 minPos [j] = getflt(pmapFile);
162 maxPos [j] = getflt(pmapFile);
163 }
164
165 /* Skip centre of gravity, and avg photon dist to it */
166 for (j = 0; j < 4; j++)
167 getflt(pmapFile);
168
169 /* Sphere radius based on avg intersphere dist
170 (= sphere distrib density ^-1/3) */
171 vol = (maxPos [0] - minPos [0]) * (maxPos [1] - minPos [1]) *
172 (maxPos [2] - minPos [2]);
173 rad = radScale * RADCOEFF * pow(vol / numSpheres, 1./3.);
174
175 /* Photon dump probability to satisfy target sphere count */
176 dumpRatio = numSpheres < numPhotons ? (float)numSpheres / numPhotons
177 : 1;
178
179 while (numPhotons-- > 0) {
180 /* Get photon position */
181 for (j = 0; j < 3; j++)
182 p.pos [j] = getflt(pmapFile);
183
184 /* Dump photon probabilistically acc. to target sphere count */
185 if (frandom() <= dumpRatio) {
186 printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
187 fputc('\n', stdout);
188 }
189
190 /* Skip photon normal and flux */
191 for (j = 0; j < 3; j++)
192 getint(sizeof(p.norm [j]), pmapFile);
193
194 #ifdef PMAP_FLOAT_FLUX
195 for (j = 0; j < 3; j++)
196 getflt(pmapFile);
197 #else
198 for (j = 0; j < 4; j++)
199 getint(1, pmapFile);
200 #endif
201
202 /* Skip primary ray index */
203 getint(sizeof(p.primary), pmapFile);
204
205 /* Skip flags */
206 getint(sizeof(p.flags), pmapFile);
207
208 if (feof(pmapFile)) {
209 sprintf(errmsg, "error reading %s", argv [arg]);
210 error(USER, errmsg);
211 }
212 }
213
214 fclose(pmapFile);
215
216 /* Reset defaults for next dump */
217 radScale = RADSCALE;
218 numSpheres = NSPHERES;
219 }
220
221 return 0;
222 }