ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.9
Committed: Sat Dec 9 18:40:43 2017 UTC (6 years, 5 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.8: +19 -10 lines
Log Message:
Fixed sphere radius for coplanar (and even colinear!) photon distribs

File Contents

# User Rev Content
1 greg 2.4 #ifndef lint
2 rschregle 2.9 static const char RCSid[] = "$Id: pmapdump.c,v 2.8 2017/08/14 21:12:10 rschregle Exp $";
3 greg 2.4 #endif
4 rschregle 2.7
5 greg 2.1 /*
6 rschregle 2.7 ======================================================================
7 greg 2.1 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 rschregle 2.3 (c) Lucerne University of Applied Sciences and Arts,
12 rschregle 2.7 supported by the Swiss National Science Foundation (SNSF, #147053)
13     ======================================================================
14 greg 2.1
15 rschregle 2.9 $Id: pmapdump.c,v 2.8 2017/08/14 21:12:10 rschregle Exp $
16 greg 2.1 */
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 greg 2.2 #include "math.h"
27 greg 2.1
28 rschregle 2.9 #define PMAPDUMP_REC "$Revision: 2.8 $"
29 rschregle 2.7
30 greg 2.1
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 rschregle 2.7 char format [128];
79 rschregle 2.9 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
80     unsigned arg, j, ptype, dim;
81 rschregle 2.7 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 greg 2.1
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 rschregle 2.6 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
137 greg 2.1 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 rschregle 2.7 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
147 greg 2.1 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 rschregle 2.7 /* Get number of photons */
159     pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
160 greg 2.1
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 rschregle 2.7 pm.minPos [j] = getflt(pmapFile);
168     pm.maxPos [j] = getflt(pmapFile);
169 greg 2.1 }
170    
171     /* Skip centre of gravity, and avg photon dist to it */
172     for (j = 0; j < 4; j++)
173     getflt(pmapFile);
174    
175 rschregle 2.9 /* 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 greg 2.1
190     /* Photon dump probability to satisfy target sphere count */
191 rschregle 2.7 dumpRatio = numSpheres < pm.numPhotons
192     ? (float)numSpheres / pm.numPhotons : 1;
193 greg 2.1
194 rschregle 2.7 /* Skip primary rays */
195     pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
196     while (pm.numPrimary-- > 0) {
197 rschregle 2.8 /* Skip source index & incident dir */
198 rschregle 2.7 getint(sizeof(pri.srcIdx) + sizeof(pri.dir), pmapFile);
199 rschregle 2.8 #ifdef PMAP_PRIMARYPOS
200     /* Skip primary hitpoint */
201 rschregle 2.7 for (j = 0; j < 3; j++)
202     getflt(pmapFile);
203 rschregle 2.8 #endif
204 rschregle 2.7 }
205    
206     #ifdef PMAP_OOC
207     /* Open leaf file with filename derived from pmap, replace pmapFile
208     * (which is currently the node file) */
209     strncpy(leafFname, argv [arg], 1024);
210     strncat(leafFname, PMAP_OOC_LEAFSUFFIX, 1024);
211     fclose(pmapFile);
212     if (!(pmapFile = fopen(leafFname, "rb"))) {
213     sprintf(errmsg, "cannot open leaf file %s", leafFname);
214     error(SYSTEM, errmsg);
215     }
216     #endif
217    
218     /* Load photons */
219     while (pm.numPhotons-- > 0) {
220     #ifdef PMAP_OOC
221     /* Get entire photon record
222     !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
223     if (!fread(&p, sizeof(p), 1, pmapFile)) {
224     sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
225     error(SYSTEM, errmsg);
226     }
227     #else
228 greg 2.1 /* Get photon position */
229     for (j = 0; j < 3; j++)
230     p.pos [j] = getflt(pmapFile);
231 rschregle 2.7 #endif
232 greg 2.1 /* Dump photon probabilistically acc. to target sphere count */
233     if (frandom() <= dumpRatio) {
234     printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
235     fputc('\n', stdout);
236     }
237    
238 rschregle 2.7 #ifndef PMAP_OOC
239 greg 2.1 /* Skip photon normal and flux */
240     for (j = 0; j < 3; j++)
241     getint(sizeof(p.norm [j]), pmapFile);
242    
243 rschregle 2.7 #ifdef PMAP_FLOAT_FLUX
244     for (j = 0; j < 3; j++)
245     getflt(pmapFile);
246     #else
247     for (j = 0; j < 4; j++)
248     getint(1, pmapFile);
249     #endif
250 greg 2.1
251     /* Skip primary ray index */
252     getint(sizeof(p.primary), pmapFile);
253    
254     /* Skip flags */
255     getint(sizeof(p.flags), pmapFile);
256 rschregle 2.7 #endif
257 greg 2.1
258 rschregle 2.7 if (ferror(pmapFile) || feof(pmapFile)) {
259 greg 2.1 sprintf(errmsg, "error reading %s", argv [arg]);
260     error(USER, errmsg);
261     }
262     }
263    
264     fclose(pmapFile);
265    
266     /* Reset defaults for next dump */
267     radScale = RADSCALE;
268     numSpheres = NSPHERES;
269     }
270    
271     return 0;
272     }