ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
Revision: 2.10
Committed: Fri Aug 7 01:21:13 2020 UTC (3 years, 9 months ago) by rschregle
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.9: +80 -37 lines
Log Message:
feat(mkpmap): Extended -apo option to reorient photon ports.

File Contents

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