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

# User Rev Content
1 greg 2.4 #ifndef lint
2 rschregle 2.10 static const char RCSid[] = "$Id: pmapdump.c,v 2.9 2017/12/09 18:40:43 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.10 $Id: pmapdump.c,v 2.9 2017/12/09 18:40:43 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.10 #define PMAPDUMP_REC "$Revision: 2.9 $"
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.10 getint(sizeof(pri.srcIdx), pmapFile);
199     #ifdef PMAP_PRIMARYDIR
200     /* Skip primary incident dir */
201     getint(sizeof(pri.dir), pmapFile);
202     #endif
203 rschregle 2.8 #ifdef PMAP_PRIMARYPOS
204     /* Skip primary hitpoint */
205 rschregle 2.7 for (j = 0; j < 3; j++)
206     getflt(pmapFile);
207 rschregle 2.8 #endif
208 rschregle 2.7 }
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 greg 2.1 /* Get photon position */
233     for (j = 0; j < 3; j++)
234     p.pos [j] = getflt(pmapFile);
235 rschregle 2.7 #endif
236 greg 2.1 /* 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 rschregle 2.7 #ifndef PMAP_OOC
243 greg 2.1 /* Skip photon normal and flux */
244     for (j = 0; j < 3; j++)
245     getint(sizeof(p.norm [j]), pmapFile);
246    
247 rschregle 2.7 #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 greg 2.1
255     /* Skip primary ray index */
256     getint(sizeof(p.primary), pmapFile);
257    
258     /* Skip flags */
259     getint(sizeof(p.flags), pmapFile);
260 rschregle 2.7 #endif
261 greg 2.1
262 rschregle 2.7 if (ferror(pmapFile) || feof(pmapFile)) {
263 greg 2.1 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     }