ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.8
Committed: Fri Feb 2 19:47:55 2018 UTC (6 years, 3 months ago) by rschregle
Content type: text/plain
Branch: MAIN
Changes since 2.7: +89 -58 lines
Log Message:
Added -lr, -ld options to mkpmap, enabled -api

File Contents

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