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 (9 years, 2 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

# User Rev Content
1 greg 2.4 #ifndef lint
2 rschregle 2.6 static const char RCSid[] = "$Id: pmapdump.c,v 4.19 2016/02/04 19:34:44 taschreg Exp taschreg $";
3 greg 2.4 #endif
4 greg 2.1 /*
5 rschregle 2.3 ==================================================================
6 greg 2.1 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 rschregle 2.3 (c) Lucerne University of Applied Sciences and Arts,
11     supported by the Swiss National Science Foundation (SNSF, #147053)
12 greg 2.1 ==================================================================
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 greg 2.2 #include "math.h"
25 greg 2.1
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 rschregle 2.6 static char header [] = "$Revision: 4.19 $";
43 greg 2.1
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 rschregle 2.6 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
131 greg 2.1 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 greg 2.2 rad = radScale * RADCOEFF * pow(vol / numSpheres, 1./3.);
174 greg 2.1
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     }