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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: mkpmap.c,v 2.7 2017/12/09 18:38:57 rschregle Exp $";
3 #endif
4
5
6 /*
7 ======================================================================
8 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 (c) Lucerne University of Applied Sciences and Arts,
14 supported by the Swiss National Science Foundation (SNSF, #147053)
15 ======================================================================
16
17 $Id: mkpmap.c,v 2.7 2017/12/09 18:38:57 rschregle Exp $
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 /* Enable options for Ze Ekspertz only! */
34 #define PMAP_EKSPERTZ
35
36
37 extern char VersionID [];
38
39
40 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
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
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 colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU));
119 printf("-me %.2e %.2e %.2e\t\t# extinction coefficient\n",
120 colval(cextinction,RED), colval(cextinction,GRN),
121 colval(cextinction,BLU));
122 printf("-mg %.2f\t\t\t\t# scattering eccentricity\n", seccg);
123 #if NIX
124 /* Multiprocessing on NIX only */
125 printf("-n %d\t\t\t\t\t# number of parallel processes\n", nproc);
126 #endif
127 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 }
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 #define check_bool(olen, var) switch (argv [i][olen]) { \
140 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 }
197
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
252 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 }
259
260 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 #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 else if (!strcmp(argv [i] + 2, "pi")) {
280 unsigned j, n = pmapNumROI;
281 check(4, "ffffff");
282
283 pmapROI = realloc(pmapROI,
284 ++pmapNumROI * sizeof(PhotonMapROI));
285 if (!pmapROI)
286 error(SYSTEM, "failed to allocate ROI");
287
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 #endif
301 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 /* Get port modifiers from file */
322 rval = wordfile(portLp, AMBLLEN-(portLp-amblist),
323 getpath(argv [++i], getrlibpath(), R_OK));
324
325 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 rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
355 getpath(argv [++i], getrlibpath(), R_OK));
356
357 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 check_bool(3, backvis);
380 }
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 check_bool(3, clobber);
410 }
411
412 else goto badopt;
413 break;
414 #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 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 #if NIX
460 case 'n': /* Num parallel processes (NIX only) */
461 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 }
470 break;
471 #endif
472 case 't': /* Timer */
473 check(2, "i");
474 photonRepTime = atoi(argv [++i]);
475 break;
476
477 case 'v': /* Verbosity */
478 check_bool(2, verbose);
479 break;
480 #ifdef EVALDRC_HACK
481 case 'A': /* Angular source file */
482 check(2,"s");
483 angsrcfile = argv[++i];
484 break;
485 #endif
486 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 #ifdef EVALDRC_HACK
526 if (angsrcfile)
527 readobj(angsrcfile); /* load angular sources */
528 #endif
529 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 distribPhotonContrib(contribPmap, nproc);
538 else
539 distribPhotons(photonMaps, nproc);
540
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 #undef check_bool
553 return 0;
554 }