ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.3
Committed: Fri May 8 13:20:23 2015 UTC (9 years ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.2: +5 -4 lines
Log Message:
Double-counting bugfix for glow sources (thanks DGM!), revised copyright

File Contents

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