ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/mkpmap.c
(Generate patch)

Comparing ray/src/rt/mkpmap.c (file contents):
Revision 2.5 by rschregle, Tue May 17 17:39:47 2016 UTC vs.
Revision 2.14 by greg, Thu Jun 5 18:28:25 2025 UTC

# Line 2 | Line 2
2   static const char RCSid[] = "$Id$";
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
12 >       supported by the German Research Foundation
13 >       (DFG LU-204/10-2, "Fassadenintegrierte Regelsysteme" (FARESYS))
14     (c) Lucerne University of Applied Sciences and Arts,
15 <       supported by the Swiss National Science Foundation (SNSF, #147053)
15 >       supported by the Swiss National Science Foundation
16 >       (SNSF #147053, "Daylight Redirecting Components")
17 >   (c) Tokyo University of Science,
18 >       supported by the JSPS Grants-in-Aid for Scientific Research
19 >       (KAKENHI JP19KK0115, "Three-Dimensional Light Flow")
20     ======================================================================
21    
22     $Id$    
23   */
24  
25  
20
26   #include "pmap.h"
27   #include "pmapmat.h"
28 + #include "pmapsrc.h"
29   #include "pmapcontrib.h"
30   #include "pmaprand.h"
31   #include "paths.h"
32   #include "ambient.h"
33   #include "resolu.h"
34   #include "source.h"
35 + #include "func.h"
36 + #include <ctype.h>
37   #include <string.h>
38   #include <sys/stat.h>
39  
40  
41 + /* Enable options for Ze Ekspertz only! */
42 + #define PMAP_EKSPERTZ
43  
44 +
45   extern char VersionID [];
46  
47  
37
38 char*    progname;                  /* argv[0] */
48   int      dimlist [MAXDIM];          /* sampling dimensions */
49   int      ndims = 0;                 /* number of sampling dimenshunns */
50   char*    octname = NULL;            /* octree name */
# Line 47 | Line 56 | int      clobber = 0;               /* overwrite outpu
56   COLOR    cextinction = BLKCOLOR;    /* global extinction coefficient */
57   COLOR    salbedo = BLKCOLOR;        /* global scattering albedo */
58   double   seccg = 0;                 /* global scattering eccentricity */
59 < int      ambincl = -1;              /* photon port flag */
60 < char     *amblist [AMBLLEN + 1];    /* photon port list */
59 > char     *amblist [AMBLLEN + 1];    /* ambient include/exclude list */
60 > int      ambincl = -1;              /* include == 1, exclude == 0 */
61   char     *diagFile = NULL;          /* diagnostics output file */
62   int      rand_samp = 1;             /* uncorrelated random sampling */
63   unsigned nproc = 1;                 /* number of parallel processes */
# Line 57 | Line 66 | unsigned nproc = 1;                 /* number of paral
66   #endif
67  
68  
60
69   /* Dummies for linkage */
70  
71   COLOR ambval = BLKCOLOR;
72 < 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, directrelay = 1,
76 <    directvis = 1, samplendx, do_irrad = 0, ambdiv = 128, vspretest = 512,
77 <    maxdepth = 6, contrib = 0;
78 < char *shm_boundary = NULL, *ambfile = NULL, *RCCONTEXT = NULL;
79 < void (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
72 > 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     *ambfile = NULL, *RCCONTEXT = NULL;
79 > void     (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
80  
73
81    
82   void printdefaults()
83   /* print default values to stdout */
84   {
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
85   #ifdef EVALDRC_HACK
86 <   /* ... and ziss one... */
86 >   /* EvalDRC support */
87     puts("-A\t\t\t\t# angular source file");
88 + #endif    
89 +   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 + #ifdef PMAP_EKSPERTZ
94 +   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   #endif
97 +   puts("-apg file nPhotons\t\t\t# global photon map");
98 +   puts("-apc file nPhotons\t\t\t# caustic photon map");
99 +   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 +   /* Kept for backwards compat, will be gradually phased out by -ld, -lr */
107 +   printf("-apm %ld\t\t\t\t# limit photon bounces\n", photonMaxBounce);
108 + #endif
109 +   puts("-apo+ mod\t\t\t\t# photon port modifier");
110 +   puts("-apO+ file\t\t\t\t# photon ports from file");
111 +   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 +   puts("-apS file\t\t\t\t# antimatter sensors from file");
115 +
116 +   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 +   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 +   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 + #ifdef PMAP_EKSPERTZ
128 +   /* (Formerly) NU STUFF for Ze Exspertz! */      
129 +   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 +   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 +   printf("-mg  %.2f\t\t\t\t# scattering eccentricity\n", seccg);
142 + #if NIX  
143 +   /* Multiprocessing on NIX only; so tuff luck, Windoze Weenies! */
144 +   printf("-n   %d\t\t\t\t\t# number of parallel processes\n", nproc);
145 + #endif  
146 +   printf("-t   %-9d\t\t\t\t# time between reports\n", photonRepTime);
147 +   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   }
152  
153  
134
135
154   int main (int argc, char* argv [])
155   {
156 <   #define check(ol, al) if (argv [i][ol] || \
157 <                             badarg(argc - i - 1,argv + i + 1, al)) \
158 <                            goto badopt
159 <                            
156 >   #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     #define check_bool(olen, var) switch (argv [i][olen]) { \
162 <                             case '\0': var = !var; break; \
163 <                             case 'y': case 'Y': case 't': case 'T': \
164 <                             case '+': case '1': var = 1; break; \
165 <                             case 'n': case 'N': case 'f': case 'F': \
166 <                             case '-': case '0': var = 0; break; \
167 <                             default: goto badopt; \
168 <                          }  
162 >      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, rval, i;
185 <   char **portLp = NULL, **sensLp = photonSensorList;
186 <   struct stat pmstat;
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  
190     /* Global program name */
191     progname = fixargv0(argv [0]);
192     /* Initialize object types */
193     initotypes();
194 <  
194 >   /* initialize calcomp routines */
195 >   initfunc();
196 >
197     /* Parse options */
198     for (i = 1; i < argc; i++) {
199        /* Eggs-pand arguments */
# Line 186 | Line 223 | int main (int argc, char* argv [])
223        }
224              
225        switch (argv [i][1]) {
226 <         case 'a':
227 <            if (!strcmp(argv [i] + 2, "pg")) {
228 <               /* Global photon map */
229 <               check(4, "ss");
230 <               globalPmapParams.fileName = argv [++i];
231 <               globalPmapParams.distribTarget =
232 <                  parseMultiplier(argv [++i]);
233 <               if (!globalPmapParams.distribTarget)
234 <                  goto badopt;                        
235 <               globalPmapParams.minGather = globalPmapParams.maxGather = 0;
236 <            }
237 <                              
238 <            else if (!strcmp(argv [i] + 2, "pm")) {
239 <               /* Max photon bounces */
240 <               check(4, "i");
241 <               photonMaxBounce = atol(argv [++i]);
242 <               if (!photonMaxBounce)
243 <                  goto badopt;
244 <            }
226 >         case 'a': /* Ambient */
227 >            switch (argv [i][2]) {
228 >               case 'i': /* Ambient include */
229 >               case 'I':
230 >                  check(3, "s");
231 >                  if (ambincl != 1) {
232 >                     ambincl = 1;
233 >                     amblp = amblist;
234 >                  }
235 >                  if (isupper(argv [i][2])) {
236 >                     /* Add modifiers from file */
237 >                     rval = wordfile(
238 >                        amblp, AMBLLEN - (amblp - amblist),
239 >                        getpath(argv [++i], getrlibpath(), R_OK)
240 >                     );
241 >                     if (rval < 0) {
242 >                        sprintf(
243 >                           errmsg, "cannot open ambient include file \"%s\"",
244 >                           argv [i]
245 >                        );
246 >                        error(SYSTEM, errmsg);
247 >                     }
248 >                     amblp += rval;
249 >                  }
250 >                  else {
251 >                     /* Add modifier from next arg */
252 >                     *amblp++ = savqstr(argv [++i]);
253 >                     *amblp = NULL;
254 >                  }
255 >                  break;
256 >
257 >               case 'e': /* Ambient exclude */
258 >               case 'E':
259 >                  check(3, "s");
260 >                  if (ambincl != 0) {
261 >                     ambincl = 0;
262 >                     amblp = amblist;
263 >                  }
264 >                  if (isupper(argv [i][2])) {
265 >                     /* Add modifiers from file */
266 >                     rval = wordfile(
267 >                        amblp, AMBLLEN - (amblp - amblist),
268 >                        getpath(argv [++i], getrlibpath(), R_OK)
269 >                     );
270 >                     if (rval < 0) {
271 >                        sprintf(
272 >                           errmsg, "cannot open ambient exclude file \"%s\"",
273 >                           argv [i]
274 >                        );
275 >                        error(SYSTEM, errmsg);
276 >                     }
277 >                     amblp += rval;
278 >                  }
279 >                  else {
280 >                     /* Add modifier from next arg */
281 >                     *amblp++ = savqstr(argv [++i]);
282 >                     *amblp = NULL;
283 >                  }
284 >                  break;
285              
286 <            else if (!strcmp(argv [i] + 2, "pp")) {
287 <               /* Precomputed global photon map */
288 <               check(4, "ssi");
289 <               preCompPmapParams.fileName = argv [++i];
290 <               preCompPmapParams.distribTarget =
291 <                  parseMultiplier(argv [++i]);
292 <               if (!preCompPmapParams.distribTarget)
293 <                  goto badopt;
294 <               preCompPmapParams.minGather = preCompPmapParams.maxGather =
295 <                  atoi(argv [++i]);
296 <               if (!preCompPmapParams.maxGather)
297 <                  goto badopt;
221 <            }
286 >               case 'p': /* Pmap-specific */
287 >                  switch (argv [i][3]) {
288 >                     case 'g': /* Global photon map */
289 >                        check(4, "ss");
290 >                        globalPmapParams.fileName = argv [++i];
291 >                        globalPmapParams.distribTarget =
292 >                           parseMultiplier(argv [++i]);
293 >                        if (!globalPmapParams.distribTarget)
294 >                           goto badopt;
295 >                        globalPmapParams.minGather =
296 >                           globalPmapParams.maxGather = 0;
297 >                        break;
298              
299 < #if 0
300 <            else if (!strcmp(argv [i] + 2, "ppb")) {
301 <               /* Precomputed global photon map + bias comp. */
302 <               check(5, "ssii");
303 <               preCompPmapParams.fileName = argv [++i];
304 <               preCompPmapParams.distribTarget =
305 <                  parseMultiplier(argv [++i]);
306 <               if (!preCompPmapParams.distribTarget)
307 <                  goto badopt;                      
308 <               preCompPmapParams.minGather = atoi(argv [++i]);
309 <               preCompPmapParams.maxGather = atoi(argv [++i]);
310 <               if (!preCompPmapParams.minGather ||
235 <                   preCompPmapParams.minGather >=
236 <                   preCompPmapParams.maxGather)
237 <                  goto badopt;
238 <            }
239 < #endif
299 >                     case 'p': /* Precomputed global photon map */
300 >                        check(4, "ssi");
301 >                        preCompPmapParams.fileName = argv [++i];
302 >                        preCompPmapParams.distribTarget =
303 >                           parseMultiplier(argv [++i]);
304 >                        if (!preCompPmapParams.distribTarget)
305 >                           goto badopt;
306 >                        preCompPmapParams.minGather =
307 >                           preCompPmapParams.maxGather = atoi(argv [++i]);
308 >                        if (!preCompPmapParams.maxGather)
309 >                           goto badopt;
310 >                        break;
311              
312 <            else if (!strcmp(argv [i] + 2, "pc")) {
313 <               /* Caustic photon map */
314 <               check(4, "ss");
315 <               causticPmapParams.fileName = argv [++i];
316 <               causticPmapParams.distribTarget =
317 <                  parseMultiplier(argv [++i]);
318 <               if (!causticPmapParams.distribTarget)
319 <                  goto badopt;
320 <            }
321 <            
322 <            else if (!strcmp(argv [i] + 2, "pv")) {
323 <               /* Volume photon map */
324 <               check(4, "ss");
325 <               volumePmapParams.fileName = argv [++i];
326 <               volumePmapParams.distribTarget =
327 <                  parseMultiplier(argv [++i]);
328 <               if (!volumePmapParams.distribTarget)
329 <                  goto badopt;                      
330 <            }
331 <            
332 <            else if (!strcmp(argv [i] + 2, "pd")) {
333 <               /* Direct photon map */
334 <               check(4, "ss");
335 <               directPmapParams.fileName = argv [++i];
336 <               directPmapParams.distribTarget =
337 <                  parseMultiplier(argv [++i]);
338 <               if (!directPmapParams.distribTarget)
339 <                  goto badopt;
340 <            }
341 <            
342 <            else if (!strcmp(argv [i] + 2, "pC")) {
343 <               /* Light source contribution photon map */
344 <               check(4, "ss");
345 <               contribPmapParams.fileName = argv [++i];
346 <               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 <            }  
312 >                     case 'c': /* Caustic photon map */
313 >                        check(4, "ss");
314 >                        causticPmapParams.fileName = argv [++i];
315 >                        causticPmapParams.distribTarget =
316 >                           parseMultiplier(argv [++i]);
317 >                        if (!causticPmapParams.distribTarget)
318 >                           goto badopt;
319 >                        break;
320 >                  
321 >                     case 'v': /* Volume photon map */
322 >                        check(4, "ss");
323 >                        volumePmapParams.fileName = argv [++i];
324 >                        volumePmapParams.distribTarget =
325 >                           parseMultiplier(argv [++i]);
326 >                        if (!volumePmapParams.distribTarget)
327 >                           goto badopt;
328 >                        break;
329 >                    
330 >                     case 'd': /* Direct photon map */
331 >                        check(4, "ss");
332 >                        directPmapParams.fileName = argv [++i];
333 >                        directPmapParams.distribTarget =
334 >                           parseMultiplier(argv [++i]);
335 >                        if (!directPmapParams.distribTarget)
336 >                           goto badopt;
337 >                        break;
338 >                    
339 >                     case 'C': /* Contribution photon map */
340 >                        check(4, "ss");
341 >                        contribPmapParams.fileName = argv [++i];
342 >                        contribPmapParams.distribTarget =
343 >                           parseMultiplier(argv [++i]);
344 >                        if (!contribPmapParams.distribTarget)
345 >                           goto badopt;
346 >                        break;
347  
348 < #ifdef PMAP_ROI
349 <            /* Region of interest; ziss option for ze egg-spurtz only! */
350 <            else if (!strcmp(argv [i] + 2, "pi")) {
351 <               int j;
352 <               check(4, "ffffff");
353 <               for (j = 0; j < 6; j++)
354 <                  pmapROI [j] = atof(argv [++i]);
355 <            }              
348 >                     case 'D': /* Predistribution factor */
349 >                        check(4, "f");
350 >                        preDistrib = atof(argv [++i]);
351 >                        if (preDistrib <= 0)
352 >                           error(USER, "predistrib factor must be > 0");
353 >                        break;
354 >
355 >                     case 'M': /* Max predistribution passes */
356 >                        check(4, "i");
357 >                        maxPreDistrib = atoi(argv [++i]);
358 >                        if (maxPreDistrib <= 0)
359 >                           error(USER, "max predistrib passes must be > 0");
360 >                        break;
361 >
362 > #if 1
363 >                     /* Kept for backwards compat, to be phased out by -lr */
364 >                     case 'm': /* Max photon bounces */
365 >                        check(4, "i");
366 >                        photonMaxBounce = atol(argv [++i]);
367 >                        if (photonMaxBounce <= 0)
368 >                           error(USER, "max photon bounces must be > 0");
369 >                        break;
370   #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            }                  
371  
372 <            else if (!strcmp(argv [i] + 2, "ps") ||
373 <                     !strcmp(argv [i] + 2, "pS")) {
374 <               /* Antimatter sensor */
375 <               check(4, "s");
376 <              
377 <               if (argv[i][3] == 'S') {
378 <                  /* Get sensor modifiers from file */
379 <                  rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
380 <                                  getpath(argv [++i], getrlibpath(), R_OK));
381 <                                  
382 <                  if (rval < 0) {
383 <                      sprintf(errmsg, "cannot open antimatter sensor file %s",
384 <                              argv [i]);
385 <                      error(SYSTEM, errmsg);
372 > #ifdef PMAP_EKSPERTZ
373 >                     case 'i': /* Add rectangular region of interest */
374 >                     case 'I': /* Add spherical region of interest */
375 >                        check(4, isupper(argv [j=i][3]) ? "ffff" : "ffffff");
376 >                        n = pmapNumROI;
377 >                        
378 >                        pmapROI = realloc(
379 >                           pmapROI, ++pmapNumROI * sizeof(PhotonMapROI)
380 >                        );
381 >                        if (!pmapROI)
382 >                           error(SYSTEM, "failed to allocate ROI");
383 >                        
384 >                        pmapROI [n].pos [0] = atof(argv [++i]);
385 >                        pmapROI [n].pos [1] = atof(argv [++i]);
386 >                        pmapROI [n].pos [2] = atof(argv [++i]);
387 >                        pmapROI [n].siz [0] = atof(argv [++i]);
388 >
389 >                        if (isupper(argv [j][3])) {
390 >                           /* Spherical ROI; radius^2 */
391 >                           pmapROI [n].siz [0] *= pmapROI [n].siz [0];
392 >                           PMAP_ROI_SETSPHERE(pmapROI + n);
393 >                           if (pmapROI [n].siz [0] <= FTINY)
394 >                              error(
395 >                                 USER,
396 >                                 "region of interest has invalid radius"
397 >                              );
398 >                        }
399 >                        else {
400 >                           /* Rectangular ROI */
401 >                           pmapROI [n].siz [1] = atof(argv [++i]);
402 >                           pmapROI [n].siz [2] = atof(argv [++i]);
403 >
404 >                           for (j = 0; j < 3; j++) {
405 >                              /* Pos at rectangle centre, siz symmetric */
406 >                              pmapROI [n].pos [j] = 0.5 * (
407 >                                 pmapROI [n].pos [j] + pmapROI [n].siz [j]
408 >                              );
409 >                              pmapROI [n].siz [j] = fabs(
410 >                                 pmapROI [n].siz [j] - pmapROI [n].pos [j]
411 >                              );
412 >                              if (pmapROI [n].siz [j] <= FTINY)
413 >                                 error(
414 >                                    USER,
415 >                                    "region of interest has invalid size"
416 >                                 );
417 >                           }
418 >                        }
419 >                        break;
420 > #endif
421 >
422 >                     case 'P': /* Global photon precomp ratio */
423 >                        check(4, "f");
424 >                        finalGather = atof(argv [++i]);
425 >                        if (finalGather <= 0 || finalGather > 1)
426 >                           error(
427 >                              USER, "global photon precomputation ratio "
428 >                              "must be in range ]0, 1]"
429 >                           );
430 >                        break;
431 >                    
432 >                     case 'o': /* Photon port */
433 >                     case 'O':
434 >                        /* Check for bad arg and length, taking into account
435 >                         * default forward orientation if none specified, in
436 >                         * order to maintain previous behaviour */
437 >                        check(argv [i][4] ? 5 : 4, "s");
438 >                        /* Get port orientation flags */
439 >                        check_tri(
440 >                           4, PMAP_PORTFWD, PMAP_PORTBWD, portFlags [0]
441 >                        );
442 >                        
443 >                        if (isupper(argv [i][3])) {
444 >                           /* Add port modifiers from file */
445 >                           rval = wordfile(
446 >                              portLp, MAXSET - (portLp - photonPortList),
447 >                              getpath(argv [++i], getrlibpath(), R_OK)
448 >                           );
449 >                           if (rval < 0) {
450 >                               sprintf(
451 >                                  errmsg, "cannot open photon port file %s",
452 >                                  argv [i]
453 >                               );
454 >                               error(SYSTEM, errmsg);
455 >                           }
456 >                           /* HACK: append port orientation flags to every
457 >                            * modifier; note this requires reallocation */
458 >                           for (; rval--; portLp++) {
459 >                              j = strlen(*portLp);
460 >                              if (!(*portLp = realloc(*portLp, j + 2))) {
461 >                                  sprintf(
462 >                                     errmsg,
463 >                                     "cannot allocate photon port modifiers"
464 >                                     " from file %s", argv [i]
465 >                                  );
466 >                                  error(SYSTEM, errmsg);
467 >                              }
468 >                              strcat(*portLp, portFlags);
469 >                           }
470 >                        }
471 >                        else {
472 >                           /* Append port flags to port modifier, add to
473 >                            * port list and mark of end list with NULL */
474 >                           strcpy(sbuf, argv [++i]);
475 >                           strcat(sbuf, portFlags);
476 >                           *portLp++ = savqstr(sbuf);
477 >                           *portLp = NULL;
478 >                        }
479 >                        break;
480 >                    
481 >                     case 'r': /* Random seed */
482 >                        check(4, "i");
483 >                        randSeed = atoi(argv [++i]);
484 >                        break;                  
485 >
486 >                     case 's': /* Antimatter sensor */
487 >                     case 'S':
488 >                        check(4, "s");
489 >                        if (isupper(argv[i][3])) {
490 >                           /* Add sensor modifiers from file */
491 >                           rval = wordfile(
492 >                              sensLp, MAXSET - (sensLp - photonSensorList),
493 >                              getpath(argv [++i], getrlibpath(), R_OK)
494 >                           );
495 >                           if (rval < 0) {
496 >                               sprintf(
497 >                                 errmsg,
498 >                                 "cannot open antimatter sensor file %s",
499 >                                 argv [i]
500 >                              );
501 >                              error(SYSTEM, errmsg);
502 >                           }
503 >                           sensLp += rval;
504 >                        }
505 >                        else {
506 >                           /* Append modifier to sensor list, mark end with
507 >                            * NULL */
508 >                           *sensLp++ = savqstr(argv [++i]);
509 >                           *sensLp = NULL;
510 >                        }
511 >                        break;
512 >
513 >                     default: goto badopt;
514                    }
515 +                  break;
516                    
517 <                  sensLp += rval;
362 <               }
363 <              
364 <               else {
365 <                  /* Append modifier to sensor list */
366 <                  *sensLp++ = argv [++i];
367 <                  *sensLp = NULL;
368 <               }
517 >               default: goto badopt;
518              }
370
371            else goto badopt;                  
519              break;
520 <                  
521 <         case 'b':
520 >                
521 >         case 'b': /* Back face visibility */
522              if (argv [i][2] == 'v') {
376               /* Back face visibility */
523                 check_bool(3, backvis);
524              }
379                  
525              else goto badopt;
526              break;
527                    
# Line 401 | Line 546 | int main (int argc, char* argv [])
546              diagFile = argv [++i];
547              break;
548                    
549 <         case 'f':
549 >         case 'f': /* Force overwrite */
550              if (argv [i][2] == 'o') {
406               /* Force overwrite */
551                 check_bool(3, clobber);
552              }
409                  
553              else goto badopt;
554              break;
555  
556 < #if 0
557 <         /* Heap size increment now fixed & defined by macro in pmapkdt.c */            
558 <         case 'i': /* Photon heap size increment */
559 <            check(2, "i");
560 <            photonHeapSizeInc = atol(argv [++i]);
556 > #ifdef PMAP_EKSPERTZ
557 >         case 'l': /* Limits */
558 >            switch (argv [i][2]) {
559 >               case 'd': /* Limit photon path distance */
560 >                  check(3, "f");
561 >                  photonMaxDist = atof(argv [++i]);
562 >                  if (photonMaxDist <= 0)
563 >                     error(USER, "max photon distance must be > 0");
564 >                  break;
565 >                
566 >               case 'r': /* Limit photon bounces */              
567 >                  check(3, "i");              
568 >                  photonMaxBounce = atol(argv [++i]);
569 >                  if (photonMaxBounce <= 0)
570 >                     error(USER, "max photon bounces must be > 0");
571 >                  break;
572 >              
573 >               default: goto badopt;
574 >            }
575              break;
576 < #endif            
577 <                  
576 > #endif
577 >
578           case 'm': /* Medium */
579              switch (argv[i][2]) {
580 <               case 'e':        /* Eggs-tinction coefficient */
580 >               case 'e': /* Eggs-tinction coefficient */
581                    check(3, "fff");
582 <                  setcolor(cextinction, atof(argv [i + 1]),
583 <                           atof(argv [i + 2]), atof(argv [i + 3]));
582 >                  setcolor(
583 >                     cextinction, atof(argv [i + 1]),
584 >                     atof(argv [i + 2]), atof(argv [i + 3])
585 >                  );
586                    i += 3;
587                    break;
588                                  
589                 case 'a':        /* Albedo */
590                    check(3, "fff");
591 <                  setcolor(salbedo, atof(argv [i + 1]),
592 <                           atof(argv [i + 2]), atof(argv [i + 3]));
591 >                  setcolor(
592 >                     salbedo, atof(argv [i + 1]),
593 >                     atof(argv [i + 2]), atof(argv [i + 3])
594 >                  );
595                    i += 3;
596                    break;
597                                  
# Line 442 | Line 603 | int main (int argc, char* argv [])
603                 default: goto badopt;
604              }                  
605              break;
606 <
607 <         case 'n': /* Num parallel processes */
606 >            
607 > #if NIX
608 >         case 'n': /* Num parallel processes (NIX only) */
609              check(2, "i");
610              nproc = atoi(argv [++i]);
611              
612              if (nproc > PMAP_MAXPROC) {
613                 nproc = PMAP_MAXPROC;
614 <               sprintf(errmsg, "too many parallel processes, clamping to "
615 <                       "%d\n", nproc);
614 >               sprintf(
615 >                  errmsg, "too many parallel processes, clamping to %d\n",
616 >                  nproc
617 >               );
618                 error(WARNING, errmsg);
619              }
620 <            
621 <            break;                  
622 <            
620 >            break;
621 > #endif
622 >
623           case 't': /* Timer */
624              check(2, "i");
625              photonRepTime = atoi(argv [++i]);
626              break;
627 <
627 >            
628 >         case 'v':   /* Verbosity */
629 >            check_bool(2, verbose);
630 >            break;
631 >            
632   #ifdef EVALDRC_HACK
633           case 'A':   /* Angular source file */
634              check(2,"s");
635              angsrcfile = argv[++i];
636 <            break;                  
636 >            break;
637   #endif
638 <                  
639 <         default: goto badopt;
638 >
639 >        default: goto badopt;
640        }
641     }
642    
643     /* Open diagnostics file */
644     if (diagFile) {
645 <      if (!freopen(diagFile, "a", stderr)) quit(2);
645 >      if (!freopen(diagFile, "a", stderr))
646 >         quit(2);
647        fprintf(stderr, "**************\n*** PID %5d: ", getpid());
648        printargs(argc, argv, stderr);
649        putc('\n', stderr);
# Line 494 | Line 663 | int main (int argc, char* argv [])
663        setPmapParam(photonMaps + i, pmapParams + i);
664        
665        /* Don't overwrite existing photon map unless clobbering enabled */
666 <      if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
667 <          !clobber) {
668 <         sprintf(errmsg, "photon map file %s exists, not overwritten",
669 <                 photonMaps [i] -> fileName);
666 >      if (
667 >         photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
668 >         !clobber
669 >      ) {
670 >         sprintf(
671 >            errmsg, "photon map file %s exists, not overwritten",
672 >           photonMaps [i] -> fileName
673 >         );
674           error(USER, errmsg);
675        }
676     }
677        
678 <   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);  
678 >   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);
679     if (i >= NUM_PMAP_TYPES)
680        error(USER, "no photon maps specified");
681    
682     readoct(octname, loadflags, &thescene, NULL);
510
683   #ifdef EVALDRC_HACK  
684     if (angsrcfile)
685        readobj(angsrcfile);    /* load angular sources */
686 < #endif      
515 <      
686 > #endif        
687     nsceneobjs = nobjects;
688    
689     /* Get sources */
# Line 539 | Line 710 | badopt:
710     #undef check_bool
711     return 0;
712   }
713 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines