ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.11
Committed: Wed Apr 14 11:26:25 2021 UTC (3 years, 1 month ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.10: +151 -89 lines
Log Message:
feat(mkpmap): Added -apI option for spherical ROI

File Contents

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