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

# Content
1 #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 /*
6 ======================================================================
7 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 (c) Lucerne University of Applied Sciences and Arts,
13 supported by the Swiss National Science Foundation (SNSF, #147053)
14 ======================================================================
15
16 $Id: mkpmap.c,v 4.18 2015/12/02 17:45:19 taschreg Exp taschreg $
17 */
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 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
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 #if 0
107 /* Heap size increment now fixed & defined by macro in pmapkdt.c */
108 printf("-i %-9ld\t\t\t# photon heap size increment\n",
109 photonHeapSizeInc);
110 #endif
111 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 printf("-n %d\t\t\t\t# number of parallel processes\n", nproc);
118 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
127 #ifdef EVALDRC_HACK
128 /* ... and ziss one... */
129 puts("-A\t\t\t\t# angular source file");
130 #endif
131 }
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 #define check_bool(olen, var) switch (argv [i][olen]) { \
143 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 rval = wordfile(portLp, AMBLLEN-(portLp-amblist),
321 getpath(argv [++i], getrlibpath(), R_OK));
322
323 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 rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
353 getpath(argv [++i], getrlibpath(), R_OK));
354
355 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 check_bool(3, backvis);
378 }
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 check_bool(3, clobber);
408 }
409
410 else goto badopt;
411 break;
412
413 #if 0
414 /* Heap size increment now fixed & defined by macro in pmapkdt.c */
415 case 'i': /* Photon heap size increment */
416 check(2, "i");
417 photonHeapSizeInc = atol(argv [++i]);
418 break;
419 #endif
420
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
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 case 't': /* Timer */
460 check(2, "i");
461 photonRepTime = atoi(argv [++i]);
462 break;
463
464 #ifdef EVALDRC_HACK
465 case 'A': /* Angular source file */
466 check(2,"s");
467 angsrcfile = argv[++i];
468 break;
469 #endif
470
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
511 #ifdef EVALDRC_HACK
512 if (angsrcfile)
513 readobj(angsrcfile); /* load angular sources */
514 #endif
515
516 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 distribPhotonContrib(contribPmap, nproc);
525 else
526 distribPhotons(photonMaps, nproc);
527
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 #undef check_bool
540 return 0;
541 }