ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.5
Committed: Tue May 17 17:39:47 2016 UTC (8 years ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.4: +76 -25 lines
Log Message:
Initial import of ooC photon map

File Contents

# User Rev Content
1 rschregle 2.5 #ifndef lint
2     static const char RCSid[] = "$Id: mkpmap.c,v 4.18 2015/12/02 17:45:19 taschreg Exp taschreg $";
3     #endif
4    
5 greg 2.1 /*
6 rschregle 2.5 ======================================================================
7 greg 2.1 Photon map generator
8    
9     Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
10     (c) Fraunhofer Institute for Solar Energy Systems,
11     Lucerne University of Applied Sciences & Arts
12 rschregle 2.5 (c) Lucerne University of Applied Sciences and Arts,
13     supported by the Swiss National Science Foundation (SNSF, #147053)
14     ======================================================================
15 greg 2.1
16 rschregle 2.5 $Id: mkpmap.c,v 4.18 2015/12/02 17:45:19 taschreg Exp taschreg $
17 greg 2.1 */
18    
19    
20    
21     #include "pmap.h"
22     #include "pmapmat.h"
23     #include "pmapcontrib.h"
24     #include "pmaprand.h"
25     #include "paths.h"
26     #include "ambient.h"
27     #include "resolu.h"
28     #include "source.h"
29     #include <string.h>
30     #include <sys/stat.h>
31    
32    
33    
34     extern char VersionID [];
35    
36    
37    
38 rschregle 2.5 char* progname; /* argv[0] */
39     int dimlist [MAXDIM]; /* sampling dimensions */
40     int ndims = 0; /* number of sampling dimenshunns */
41     char* octname = NULL; /* octree name */
42     CUBE thescene; /* scene top-level octree */
43     OBJECT nsceneobjs; /* number of objects in scene */
44     double srcsizerat = 0.01; /* source partition size ratio */
45     int backvis = 1; /* back face visibility */
46     int clobber = 0; /* overwrite output */
47     COLOR cextinction = BLKCOLOR; /* global extinction coefficient */
48     COLOR salbedo = BLKCOLOR; /* global scattering albedo */
49     double seccg = 0; /* global scattering eccentricity */
50     int ambincl = -1; /* photon port flag */
51     char *amblist [AMBLLEN + 1]; /* photon port list */
52     char *diagFile = NULL; /* diagnostics output file */
53     int rand_samp = 1; /* uncorrelated random sampling */
54     unsigned nproc = 1; /* number of parallel processes */
55     #ifdef EVALDRC_HACK
56     char *angsrcfile = NULL; /* angular source file for EvalDRC */
57     #endif
58    
59 greg 2.1
60    
61     /* Dummies for linkage */
62    
63     COLOR ambval = BLKCOLOR;
64     double shadthresh = .05, ambacc = 0.2, shadcert = .5, minweight = 5e-3,
65     ssampdist = 0, dstrsrc = 0.0, specthresh = 0.15, specjitter = 1.0,
66     avgrefl = 0.5;
67     int ambvwt = 0, ambssamp = 0, ambres = 32, ambounce = 0, directrelay = 1,
68     directvis = 1, samplendx, do_irrad = 0, ambdiv = 128, vspretest = 512,
69     maxdepth = 6, contrib = 0;
70     char *shm_boundary = NULL, *ambfile = NULL, *RCCONTEXT = NULL;
71     void (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
72    
73    
74    
75     void printdefaults()
76     /* print default values to stdout */
77     {
78     puts("-apg file nPhotons\t\t# global photon map");
79     puts("-apc file nPhotons\t\t# caustic photon map");
80     puts("-apd file nPhotons\t\t# direct photon map");
81     puts("-app file nPhotons bwidth\t# precomputed global photon map");
82     #if 0
83     /* Hide this option as most likely useless and confusing to user */
84     puts("-appb file nPhotons minBw maxBw\t# precomp bias comp global pmap");
85     #endif
86     puts("-apv file nPhotons\t\t# volume photon map");
87     puts("-apC file nPhotons\t\t# contribution photon map");
88    
89     printf("-apD %f\t\t\t# predistribution factor\n", preDistrib);
90     printf("-apM %d\t\t\t\t# max predistrib passes\n", maxPreDistrib);
91     printf("-apm %ld\t\t\t# max photon bounces\n", photonMaxBounce);
92     puts("-apo mod\t\t\t# photon port modifier");
93     puts("-apO file\t\t\t# photon port file");
94     printf("-apP %f\t\t\t# precomputation factor\n", finalGather);
95     printf("-apr %d\t\t\t\t# random seed\n", randSeed);
96     puts("-aps mod\t\t\t# antimatter sensor modifier");
97     puts("-apS file\t\t\t# antimatter sensor file");
98    
99     printf(backvis ? "-bv+\t\t\t\t# back face visibility on\n"
100     : "-bv-\t\t\t\t# back face visibility off\n");
101     printf("-dp %.1f\t\t\t# PDF samples / sr\n", pdfSamples);
102     printf("-ds %f\t\t\t# source partition size ratio\n", srcsizerat);
103     printf("-e %s\t\t\t# diagnostics output file\n", diagFile);
104     printf(clobber ? "-fo+\t\t\t\t# force overwrite"
105     : "-fo-\t\t\t\t# do not overwrite\n");
106 rschregle 2.5 #if 0
107     /* Heap size increment now fixed & defined by macro in pmapkdt.c */
108 greg 2.1 printf("-i %-9ld\t\t\t# photon heap size increment\n",
109     photonHeapSizeInc);
110 rschregle 2.5 #endif
111 greg 2.1 printf("-ma %.2f %.2f %.2f\t\t# scattering albedo\n",
112     colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU));
113     printf("-me %.2e %.2e %.2e\t# extinction coefficient\n",
114     colval(cextinction,RED), colval(cextinction,GRN),
115     colval(cextinction,BLU));
116     printf("-mg %.2f\t\t\t# scattering eccentricity\n", seccg);
117 rschregle 2.5 printf("-n %d\t\t\t\t# number of parallel processes\n", nproc);
118 greg 2.1 printf("-t %-9d\t\t\t# time between reports\n", photonRepTime);
119    
120     #ifdef PMAP_ROI
121     /* Ziss option for ze egg-spurtz only! */
122     printf("-api \t%.0e %.0e %.0e\n\t%.0e %.0e %.0e\t# region of interest\n",
123     pmapROI [0], pmapROI [1], pmapROI [2], pmapROI [3],
124     pmapROI [4], pmapROI [5]);
125     #endif
126 rschregle 2.5
127     #ifdef EVALDRC_HACK
128     /* ... and ziss one... */
129     puts("-A\t\t\t\t# angular source file");
130     #endif
131 greg 2.1 }
132    
133    
134    
135    
136     int main (int argc, char* argv [])
137     {
138     #define check(ol, al) if (argv [i][ol] || \
139     badarg(argc - i - 1,argv + i + 1, al)) \
140     goto badopt
141    
142 schorsch 2.3 #define check_bool(olen, var) switch (argv [i][olen]) { \
143 greg 2.1 case '\0': var = !var; break; \
144     case 'y': case 'Y': case 't': case 'T': \
145     case '+': case '1': var = 1; break; \
146     case 'n': case 'N': case 'f': case 'F': \
147     case '-': case '0': var = 0; break; \
148     default: goto badopt; \
149     }
150    
151     int loadflags = IO_CHECK | IO_SCENE | IO_TREE | IO_BOUNDS, rval, i;
152     char **portLp = NULL, **sensLp = photonSensorList;
153     struct stat pmstat;
154    
155     /* Global program name */
156     progname = fixargv0(argv [0]);
157     /* Initialize object types */
158     initotypes();
159    
160     /* Parse options */
161     for (i = 1; i < argc; i++) {
162     /* Eggs-pand arguments */
163     while ((rval = expandarg(&argc, &argv, i)))
164     if (rval < 0) {
165     sprintf(errmsg, "cannot eggs-pand '%s'", argv [i]);
166     error(SYSTEM, errmsg);
167     }
168    
169     if (argv[i] == NULL)
170     break;
171    
172     if (!strcmp(argv [i], "-version")) {
173     puts(VersionID);
174     quit(0);
175     }
176    
177     if (!strcmp(argv [i], "-defaults") || !strcmp(argv [i], "-help")) {
178     printdefaults();
179     quit(0);
180     }
181    
182     /* Get octree */
183     if (i == argc - 1) {
184     octname = argv [i];
185     break;
186     }
187    
188     switch (argv [i][1]) {
189     case 'a':
190     if (!strcmp(argv [i] + 2, "pg")) {
191     /* Global photon map */
192     check(4, "ss");
193     globalPmapParams.fileName = argv [++i];
194     globalPmapParams.distribTarget =
195     parseMultiplier(argv [++i]);
196     if (!globalPmapParams.distribTarget)
197     goto badopt;
198     globalPmapParams.minGather = globalPmapParams.maxGather = 0;
199     }
200    
201     else if (!strcmp(argv [i] + 2, "pm")) {
202     /* Max photon bounces */
203     check(4, "i");
204     photonMaxBounce = atol(argv [++i]);
205     if (!photonMaxBounce)
206     goto badopt;
207     }
208    
209     else if (!strcmp(argv [i] + 2, "pp")) {
210     /* Precomputed global photon map */
211     check(4, "ssi");
212     preCompPmapParams.fileName = argv [++i];
213     preCompPmapParams.distribTarget =
214     parseMultiplier(argv [++i]);
215     if (!preCompPmapParams.distribTarget)
216     goto badopt;
217     preCompPmapParams.minGather = preCompPmapParams.maxGather =
218     atoi(argv [++i]);
219     if (!preCompPmapParams.maxGather)
220     goto badopt;
221     }
222    
223     #if 0
224     else if (!strcmp(argv [i] + 2, "ppb")) {
225     /* Precomputed global photon map + bias comp. */
226     check(5, "ssii");
227     preCompPmapParams.fileName = argv [++i];
228     preCompPmapParams.distribTarget =
229     parseMultiplier(argv [++i]);
230     if (!preCompPmapParams.distribTarget)
231     goto badopt;
232     preCompPmapParams.minGather = atoi(argv [++i]);
233     preCompPmapParams.maxGather = atoi(argv [++i]);
234     if (!preCompPmapParams.minGather ||
235     preCompPmapParams.minGather >=
236     preCompPmapParams.maxGather)
237     goto badopt;
238     }
239     #endif
240    
241     else if (!strcmp(argv [i] + 2, "pc")) {
242     /* Caustic photon map */
243     check(4, "ss");
244     causticPmapParams.fileName = argv [++i];
245     causticPmapParams.distribTarget =
246     parseMultiplier(argv [++i]);
247     if (!causticPmapParams.distribTarget)
248     goto badopt;
249     }
250    
251     else if (!strcmp(argv [i] + 2, "pv")) {
252     /* Volume photon map */
253     check(4, "ss");
254     volumePmapParams.fileName = argv [++i];
255     volumePmapParams.distribTarget =
256     parseMultiplier(argv [++i]);
257     if (!volumePmapParams.distribTarget)
258     goto badopt;
259     }
260    
261     else if (!strcmp(argv [i] + 2, "pd")) {
262     /* Direct photon map */
263     check(4, "ss");
264     directPmapParams.fileName = argv [++i];
265     directPmapParams.distribTarget =
266     parseMultiplier(argv [++i]);
267     if (!directPmapParams.distribTarget)
268     goto badopt;
269     }
270    
271     else if (!strcmp(argv [i] + 2, "pC")) {
272     /* Light source contribution photon map */
273     check(4, "ss");
274     contribPmapParams.fileName = argv [++i];
275     contribPmapParams.distribTarget =
276     parseMultiplier(argv [++i]);
277     if (!contribPmapParams.distribTarget)
278     goto badopt;
279     }
280    
281     else if (!strcmp(argv [i] + 2, "pD")) {
282     /* Predistribution factor */
283     check(4, "f");
284     preDistrib = atof(argv [++i]);
285     if (preDistrib <= 0)
286     error(USER, "predistribution factor must be > 0");
287     }
288    
289     #ifdef PMAP_ROI
290     /* Region of interest; ziss option for ze egg-spurtz only! */
291     else if (!strcmp(argv [i] + 2, "pi")) {
292     int j;
293     check(4, "ffffff");
294     for (j = 0; j < 6; j++)
295     pmapROI [j] = atof(argv [++i]);
296     }
297     #endif
298    
299     else if (!strcmp(argv [i] + 2, "pP")) {
300     /* Global photon precomputation factor */
301     check(4, "f");
302     finalGather = atof(argv [++i]);
303     if (finalGather <= 0 || finalGather > 1)
304     error(USER, "global photon precomputation factor "
305     "must be in range ]0, 1]");
306     }
307    
308     else if (!strcmp(argv [i] + 2, "po") ||
309     !strcmp(argv [i] + 2, "pO")) {
310     /* Photon port */
311     check(4, "s");
312    
313     if (ambincl != 1) {
314     ambincl = 1;
315     portLp = amblist;
316     }
317    
318     if (argv[i][3] == 'O') {
319     /* Get port modifiers file */
320 greg 2.4 rval = wordfile(portLp, AMBLLEN-(portLp-amblist),
321 rschregle 2.5 getpath(argv [++i], getrlibpath(), R_OK));
322    
323 greg 2.1 if (rval < 0) {
324     sprintf(errmsg, "cannot open photon port file %s",
325     argv [i]);
326     error(SYSTEM, errmsg);
327     }
328    
329     portLp += rval;
330     }
331    
332     else {
333     /* Append modifier to port list */
334     *portLp++ = argv [++i];
335     *portLp = NULL;
336     }
337     }
338    
339     else if (!strcmp(argv [i] + 2, "pr")) {
340     /* Random seed */
341     check(4, "i");
342     randSeed = atoi(argv [++i]);
343     }
344    
345     else if (!strcmp(argv [i] + 2, "ps") ||
346     !strcmp(argv [i] + 2, "pS")) {
347     /* Antimatter sensor */
348     check(4, "s");
349    
350     if (argv[i][3] == 'S') {
351     /* Get sensor modifiers from file */
352 greg 2.4 rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
353 rschregle 2.5 getpath(argv [++i], getrlibpath(), R_OK));
354    
355 greg 2.1 if (rval < 0) {
356     sprintf(errmsg, "cannot open antimatter sensor file %s",
357     argv [i]);
358     error(SYSTEM, errmsg);
359     }
360    
361     sensLp += rval;
362     }
363    
364     else {
365     /* Append modifier to sensor list */
366     *sensLp++ = argv [++i];
367     *sensLp = NULL;
368     }
369     }
370    
371     else goto badopt;
372     break;
373    
374     case 'b':
375     if (argv [i][2] == 'v') {
376     /* Back face visibility */
377 schorsch 2.3 check_bool(3, backvis);
378 greg 2.1 }
379    
380     else goto badopt;
381     break;
382    
383     case 'd': /* Direct */
384     switch (argv [i][2]) {
385     case 'p': /* PDF samples */
386     check(3, "f");
387     pdfSamples = atof(argv [++i]);
388     break;
389    
390     case 's': /* Source partition size ratio */
391     check(3, "f");
392     srcsizerat = atof(argv [++i]);
393     break;
394    
395     default: goto badopt;
396     }
397     break;
398    
399     case 'e': /* Diagnostics file */
400     check(2, "s");
401     diagFile = argv [++i];
402     break;
403    
404     case 'f':
405     if (argv [i][2] == 'o') {
406     /* Force overwrite */
407 schorsch 2.3 check_bool(3, clobber);
408 greg 2.1 }
409    
410     else goto badopt;
411     break;
412 rschregle 2.5
413     #if 0
414     /* Heap size increment now fixed & defined by macro in pmapkdt.c */
415 greg 2.1 case 'i': /* Photon heap size increment */
416     check(2, "i");
417     photonHeapSizeInc = atol(argv [++i]);
418     break;
419 rschregle 2.5 #endif
420 greg 2.1
421     case 'm': /* Medium */
422     switch (argv[i][2]) {
423     case 'e': /* Eggs-tinction coefficient */
424     check(3, "fff");
425     setcolor(cextinction, atof(argv [i + 1]),
426     atof(argv [i + 2]), atof(argv [i + 3]));
427     i += 3;
428     break;
429    
430     case 'a': /* Albedo */
431     check(3, "fff");
432     setcolor(salbedo, atof(argv [i + 1]),
433     atof(argv [i + 2]), atof(argv [i + 3]));
434     i += 3;
435     break;
436    
437     case 'g': /* Scattering eccentricity */
438     check(3, "f");
439     seccg = atof(argv [++i]);
440     break;
441    
442     default: goto badopt;
443     }
444     break;
445 rschregle 2.5
446     case 'n': /* Num parallel processes */
447     check(2, "i");
448     nproc = atoi(argv [++i]);
449    
450     if (nproc > PMAP_MAXPROC) {
451     nproc = PMAP_MAXPROC;
452     sprintf(errmsg, "too many parallel processes, clamping to "
453     "%d\n", nproc);
454     error(WARNING, errmsg);
455     }
456    
457     break;
458    
459 greg 2.1 case 't': /* Timer */
460     check(2, "i");
461     photonRepTime = atoi(argv [++i]);
462     break;
463 rschregle 2.5
464     #ifdef EVALDRC_HACK
465     case 'A': /* Angular source file */
466     check(2,"s");
467     angsrcfile = argv[++i];
468     break;
469     #endif
470 greg 2.1
471     default: goto badopt;
472     }
473     }
474    
475     /* Open diagnostics file */
476     if (diagFile) {
477     if (!freopen(diagFile, "a", stderr)) quit(2);
478     fprintf(stderr, "**************\n*** PID %5d: ", getpid());
479     printargs(argc, argv, stderr);
480     putc('\n', stderr);
481     fflush(stderr);
482     }
483    
484     #ifdef NICE
485     /* Lower priority */
486     nice(NICE);
487     #endif
488    
489     if (octname == NULL)
490     error(USER, "missing octree argument");
491    
492     /* Allocate photon maps and set parameters */
493     for (i = 0; i < NUM_PMAP_TYPES; i++) {
494     setPmapParam(photonMaps + i, pmapParams + i);
495    
496     /* Don't overwrite existing photon map unless clobbering enabled */
497     if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
498     !clobber) {
499     sprintf(errmsg, "photon map file %s exists, not overwritten",
500     photonMaps [i] -> fileName);
501     error(USER, errmsg);
502     }
503     }
504    
505     for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);
506     if (i >= NUM_PMAP_TYPES)
507     error(USER, "no photon maps specified");
508    
509     readoct(octname, loadflags, &thescene, NULL);
510 rschregle 2.5
511     #ifdef EVALDRC_HACK
512     if (angsrcfile)
513     readobj(angsrcfile); /* load angular sources */
514     #endif
515    
516 greg 2.1 nsceneobjs = nobjects;
517    
518     /* Get sources */
519     marksources();
520    
521     /* Do forward pass and build photon maps */
522     if (contribPmap)
523     /* Just build contrib pmap, ignore others */
524 rschregle 2.5 distribPhotonContrib(contribPmap, nproc);
525 greg 2.1 else
526 rschregle 2.5 distribPhotons(photonMaps, nproc);
527 greg 2.1
528     /* Save photon maps; no idea why GCC needs an explicit cast here... */
529     savePmaps((const PhotonMap**)photonMaps, argc, argv);
530     cleanUpPmaps(photonMaps);
531    
532     quit(0);
533    
534     badopt:
535     sprintf(errmsg, "command line error at '%s'", argv[i]);
536     error(USER, errmsg);
537    
538     #undef check
539 schorsch 2.3 #undef check_bool
540 greg 2.1 return 0;
541     }