ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.1
Committed: Tue Feb 24 19:39:27 2015 UTC (10 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial check-in of photon map addition by Roland Schregle

File Contents

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