ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/pmapdump.c
Revision: 2.12
Committed: Wed Nov 21 19:30:59 2018 UTC (6 years, 5 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.11: +37 -20 lines
Log Message:
Added -c option to specify custom sphere colours

File Contents

# User Rev Content
1 greg 2.4 #ifndef lint
2 rschregle 2.12 static const char RCSid[] = "$Id: pmapdump.c,v 2.11 2018/08/02 18:33:49 greg 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.12 $Id: pmapdump.c,v 2.11 2018/08/02 18:33:49 greg 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.12 #define PMAPDUMP_REC "$Revision: 2.11 $"
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     const RadianceDef radDefs [] = {
47 rschregle 2.12 { "void plastic mat.global\n0\n0\n5 %f %f %f 0 0\n",
48 greg 2.1 "mat.global sphere obj.global\n0\n0\n4 %g %g %g %g\n"
49     },
50 rschregle 2.12 { "void plastic mat.pglobal\n0\n0\n5 %f %f %f 0 0\n",
51 greg 2.1 "mat.pglobal sphere obj.global\n0\n0\n4 %g %g %g %g\n"
52     },
53 rschregle 2.12 { "void plastic mat.caustic\n0\n0\n5 %f %f %f 0 0\n",
54 greg 2.1 "mat.caustic sphere obj.caustic\n0\n0\n4 %g %g %g %g\n"
55     },
56 rschregle 2.12 { "void plastic mat.volume\n0\n0\n5 %f %f %f 0 0\n",
57 greg 2.1 "mat.volume sphere obj.volume\n0\n0\n4 %g %g %g %g\n"
58     },
59 rschregle 2.12 { "void plastic mat.direct\n0\n0\n5 %f %f %f 0 0\n",
60 greg 2.1 "mat.direct sphere obj.direct\n0\n0\n4 %g %g %g %g\n"
61     },
62 rschregle 2.12 { "void plastic mat.contrib\n0\n0\n5 %f %f %f 0 0\n",
63 greg 2.1 "mat.contrib sphere obj.contrib\n0\n0\n4 %g %g %g %g\n"
64     }
65     };
66    
67 rschregle 2.12 /* Default colour codes are as follows: global = blue
68     precomp global = cyan
69     caustic = red
70     volume = green
71     direct = magenta
72     contrib = yellow */
73     const COLOR colDefs [] = {
74     {0, 0, 1}, {0, 1, 1}, {1, 0, 0}, {0, 1, 0}, {1, 0, 1}, {1, 1, 0}
75     };
76 greg 2.1
77    
78     int main (int argc, char** argv)
79     {
80 greg 2.11 char format [MAXFMTLEN];
81 rschregle 2.9 RREAL rad, radScale = RADSCALE, extent, dumpRatio;
82     unsigned arg, j, ptype, dim;
83 rschregle 2.7 long numSpheres = NSPHERES;
84 rschregle 2.12 COLOR customCol = {0, 0, 0};
85 rschregle 2.7 FILE *pmapFile;
86     PhotonMap pm;
87     PhotonPrimary pri;
88     Photon p;
89     #ifdef PMAP_OOC
90     char leafFname [1024];
91     #endif
92 greg 2.1
93     if (argc < 2) {
94     puts("Dump photon maps as RADIANCE scene description\n");
95 rschregle 2.12 printf("Usage: %s "
96     "[-r radscale1] [-n nspheres1] [-c rcol1 gcol1 bcol1] pmap1 "
97     "[-r radscale2] [-n nspheres2] [-c rcol2 gcol2 bcol2] pmap2 "
98     "...\n", argv [0]);
99 greg 2.1 return 1;
100     }
101    
102     for (arg = 1; arg < argc; arg++) {
103     /* Parse options */
104     if (argv [arg][0] == '-') {
105     switch (argv [arg][1]) {
106     case 'r':
107     if ((radScale = atof(argv [++arg])) <= 0)
108     error(USER, "invalid radius scale");
109     break;
110    
111     case 'n':
112     if ((numSpheres = parseMultiplier(argv [++arg])) <= 0)
113     error(USER, "invalid number of spheres");
114     break;
115    
116 rschregle 2.12 case 'c':
117     for (j = 0; j < 3; j++)
118     if ((customCol [j] = atof(argv [++arg])) <= 0)
119     error(USER, "invalid RGB colour");
120     break;
121    
122 greg 2.1 default:
123     sprintf(errmsg, "unknown option %s", argv [arg]);
124     error(USER, errmsg);
125     return -1;
126     }
127    
128     continue;
129     }
130    
131     /* Dump photon map */
132     if (!(pmapFile = fopen(argv [arg], "rb"))) {
133     sprintf(errmsg, "can't open %s", argv [arg]);
134     error(SYSTEM, errmsg);
135     }
136    
137     /* Get format string */
138     strcpy(format, PMAP_FORMAT_GLOB);
139     if (checkheader(pmapFile, format, NULL) != 1) {
140     sprintf(errmsg, "photon map file %s has unknown format %s",
141     argv [arg], format);
142     error(USER, errmsg);
143     }
144    
145     /* Identify photon map type from format string */
146     for (ptype = 0;
147 rschregle 2.6 ptype < NUM_PMAP_TYPES && strcmp(pmapFormat [ptype], format);
148 greg 2.1 ptype++);
149    
150     if (!validPmapType(ptype)) {
151     sprintf(errmsg, "file %s contains an unknown photon map type",
152     argv [arg]);
153     error(USER, errmsg);
154     }
155    
156     /* Get file format version and check for compatibility */
157 rschregle 2.7 if (strcmp(getstr(format, pmapFile), PMAP_FILEVER))
158 greg 2.1 error(USER, "incompatible photon map file format");
159    
160     /* Dump command line as comment */
161     fputs("# ", stdout);
162     printargs(argc, argv, stdout);
163     fputc('\n', stdout);
164    
165 rschregle 2.12 /* Dump material def */
166     if (intens(customCol) > 0)
167     printf(radDefs [ptype].mat,
168     customCol [0], customCol [1], customCol [2]);
169     else
170     printf(radDefs [ptype].mat,
171     colDefs [ptype][0], colDefs [ptype][1], colDefs [ptype][2]);
172 greg 2.1 fputc('\n', stdout);
173    
174 rschregle 2.7 /* Get number of photons */
175     pm.numPhotons = getint(sizeof(pm.numPhotons), pmapFile);
176 greg 2.1
177     /* Skip avg photon flux */
178     for (j = 0; j < 3; j++)
179     getflt(pmapFile);
180    
181     /* Get distribution extent (min & max photon positions) */
182     for (j = 0; j < 3; j++) {
183 rschregle 2.7 pm.minPos [j] = getflt(pmapFile);
184     pm.maxPos [j] = getflt(pmapFile);
185 greg 2.1 }
186    
187     /* Skip centre of gravity, and avg photon dist to it */
188     for (j = 0; j < 4; j++)
189     getflt(pmapFile);
190    
191 rschregle 2.9 /* Sphere radius based on avg intersphere dist depending on
192     whether the distribution occupies a 1D line (!), a 2D plane,
193     or 3D volume (= sphere distrib density ^-1/d, where d is the
194     dimensionality of the distribution) */
195     for (j = 0, extent = 1.0, dim = 0; j < 3; j++) {
196     rad = pm.maxPos [j] - pm.minPos [j];
197    
198     if (rad > FTINY) {
199     dim++;
200     extent *= rad;
201     }
202     }
203    
204     rad = radScale * RADCOEFF * pow(extent / numSpheres, 1./dim);
205 greg 2.1
206     /* Photon dump probability to satisfy target sphere count */
207 rschregle 2.7 dumpRatio = numSpheres < pm.numPhotons
208     ? (float)numSpheres / pm.numPhotons : 1;
209 greg 2.1
210 rschregle 2.7 /* Skip primary rays */
211     pm.numPrimary = getint(sizeof(pm.numPrimary), pmapFile);
212     while (pm.numPrimary-- > 0) {
213 rschregle 2.8 /* Skip source index & incident dir */
214 rschregle 2.10 getint(sizeof(pri.srcIdx), pmapFile);
215     #ifdef PMAP_PRIMARYDIR
216     /* Skip primary incident dir */
217     getint(sizeof(pri.dir), pmapFile);
218     #endif
219 rschregle 2.8 #ifdef PMAP_PRIMARYPOS
220     /* Skip primary hitpoint */
221 rschregle 2.7 for (j = 0; j < 3; j++)
222     getflt(pmapFile);
223 rschregle 2.8 #endif
224 rschregle 2.7 }
225    
226     #ifdef PMAP_OOC
227     /* Open leaf file with filename derived from pmap, replace pmapFile
228     * (which is currently the node file) */
229     strncpy(leafFname, argv [arg], 1024);
230     strncat(leafFname, PMAP_OOC_LEAFSUFFIX, 1024);
231     fclose(pmapFile);
232     if (!(pmapFile = fopen(leafFname, "rb"))) {
233     sprintf(errmsg, "cannot open leaf file %s", leafFname);
234     error(SYSTEM, errmsg);
235     }
236     #endif
237    
238     /* Load photons */
239     while (pm.numPhotons-- > 0) {
240     #ifdef PMAP_OOC
241     /* Get entire photon record
242     !!! OOC PMAP FILES CURRENTLY DON'T USE PORTABLE I/O !!! */
243     if (!fread(&p, sizeof(p), 1, pmapFile)) {
244     sprintf(errmsg, "error reading OOC leaf file %s", leafFname);
245     error(SYSTEM, errmsg);
246     }
247     #else
248 greg 2.1 /* Get photon position */
249     for (j = 0; j < 3; j++)
250     p.pos [j] = getflt(pmapFile);
251 rschregle 2.7 #endif
252 greg 2.1 /* Dump photon probabilistically acc. to target sphere count */
253     if (frandom() <= dumpRatio) {
254     printf(radDefs [ptype].obj, p.pos [0], p.pos [1], p.pos [2], rad);
255     fputc('\n', stdout);
256     }
257    
258 rschregle 2.7 #ifndef PMAP_OOC
259 greg 2.1 /* Skip photon normal and flux */
260     for (j = 0; j < 3; j++)
261     getint(sizeof(p.norm [j]), pmapFile);
262    
263 rschregle 2.7 #ifdef PMAP_FLOAT_FLUX
264     for (j = 0; j < 3; j++)
265     getflt(pmapFile);
266     #else
267     for (j = 0; j < 4; j++)
268     getint(1, pmapFile);
269     #endif
270 greg 2.1
271     /* Skip primary ray index */
272     getint(sizeof(p.primary), pmapFile);
273    
274     /* Skip flags */
275     getint(sizeof(p.flags), pmapFile);
276 rschregle 2.7 #endif
277 greg 2.1
278 rschregle 2.7 if (ferror(pmapFile) || feof(pmapFile)) {
279 greg 2.1 sprintf(errmsg, "error reading %s", argv [arg]);
280     error(USER, errmsg);
281     }
282     }
283    
284     fclose(pmapFile);
285    
286     /* Reset defaults for next dump */
287     radScale = RADSCALE;
288     numSpheres = NSPHERES;
289 rschregle 2.12 customCol [0] = customCol [1] = customCol [2] = 0;
290 greg 2.1 }
291    
292     return 0;
293     }