ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.6
Committed: Mon Aug 14 21:12:10 2017 UTC (6 years, 8 months ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R1
Changes since 2.5: +53 -71 lines
Log Message:
Updated photon map code for Windows; no multproc or ooC for now

File Contents

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