ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.9
Committed: Tue Mar 20 19:55:33 2018 UTC (6 years, 2 months ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 2.8: +248 -196 lines
Log Message:
Added -ae/-ai ambient exclude options to mkpmap, cleaned up opt parsing.

File Contents

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