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.8 by rschregle, Fri Feb 2 19:47:55 2018 UTC vs.
Revision 2.11 by rschregle, Wed Apr 14 11:26:25 2021 UTC

# Line 9 | Line 9 | static const char RCSid[] = "$Id$";
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$    
# Line 20 | Line 25 | static const char RCSid[] = "$Id$";
25  
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 <ctype.h>
36   #include <string.h>
37   #include <sys/stat.h>
38  
# Line 49 | 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 62 | Line 69 | unsigned nproc = 1;                 /* number of paral
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     *shm_boundary = NULL, *ambfile = NULL, *RCCONTEXT = NULL;
79 > void     (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
80  
81    
82   void printdefaults()
83   /* print default values to stdout */
84   {
78
85   #ifdef EVALDRC_HACK
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# region of interest");
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");          
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");
# Line 92 | Line 103 | void printdefaults()
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 */
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 port file");
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 sensor file");
114 >   puts("-apS file\t\t\t\t# antimatter sensors from file");
115  
116 <   printf(backvis ? "-bv+\t\t\t\t\t# back face visibility on\n"
117 <                  : "-bv-\t\t\t\t\t# back face visibility off\n");
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 ? "-fo+\t\t\t\t\t# force overwrite\n"
124 <                  : "-fo-\t\t\t\t\t# do not overwrite\n");
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 <   /* NU STUFF for Ze Exspertz! */      
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("-ma  %.2f %.2f %.2f\t\t\t# scattering albedo\n",
133 <          colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU));
134 <   printf("-me  %.2e %.2e %.2e\t\t# extinction coefficient\n",
135 <          colval(cextinction,RED), colval(cextinction,GRN),
136 <          colval(cextinction,BLU));          
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 */
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 ? "-v+\t\t\t\t\t# verbose console output\n"
148 <                  : "-v-\t\t\t\t\t# terse console output\n");
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  
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]);
# Line 183 | Line 221 | int main (int argc, char* argv [])
221        }
222              
223        switch (argv [i][1]) {
224 <         case 'a':
225 <            if (!strcmp(argv [i] + 2, "pg")) {
226 <               /* Global photon map */
227 <               check(4, "ss");
228 <               globalPmapParams.fileName = argv [++i];
229 <               globalPmapParams.distribTarget =
230 <                  parseMultiplier(argv [++i]);
231 <               if (!globalPmapParams.distribTarget)
232 <                  goto badopt;                        
233 <               globalPmapParams.minGather = globalPmapParams.maxGather = 0;
234 <            }                              
224 >         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 >                  if (isupper(argv [i][2])) {
234 >                     /* Add modifiers from file */
235 >                     rval = wordfile(
236 >                        amblp, AMBLLEN - (amblp - amblist),
237 >                        getpath(argv [++i], getrlibpath(), R_OK)
238 >                     );
239 >                     if (rval < 0) {
240 >                        sprintf(
241 >                           errmsg, "cannot open ambient include file \"%s\"",
242 >                           argv [i]
243 >                        );
244 >                        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 >                  if (isupper(argv [i][2])) {
263 >                     /* Add modifiers from file */
264 >                     rval = wordfile(
265 >                        amblp, AMBLLEN - (amblp - amblist),
266 >                        getpath(argv [++i], getrlibpath(), R_OK)
267 >                     );
268 >                     if (rval < 0) {
269 >                        sprintf(
270 >                           errmsg, "cannot open ambient exclude file \"%s\"",
271 >                           argv [i]
272 >                        );
273 >                        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              
284 <            else if (!strcmp(argv [i] + 2, "pp")) {
285 <               /* Precomputed global photon map */
286 <               check(4, "ssi");
287 <               preCompPmapParams.fileName = argv [++i];
288 <               preCompPmapParams.distribTarget =
289 <                  parseMultiplier(argv [++i]);
290 <               if (!preCompPmapParams.distribTarget)
291 <                  goto badopt;
292 <               preCompPmapParams.minGather = preCompPmapParams.maxGather =
293 <                  atoi(argv [++i]);
294 <               if (!preCompPmapParams.maxGather)
295 <                  goto badopt;
210 <            }
284 >               case 'p': /* Pmap-specific */
285 >                  switch (argv [i][3]) {
286 >                     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 >                           goto badopt;
293 >                        globalPmapParams.minGather =
294 >                           globalPmapParams.maxGather = 0;
295 >                        break;
296              
297 <            else if (!strcmp(argv [i] + 2, "pc")) {
298 <               /* Caustic photon map */
299 <               check(4, "ss");
300 <               causticPmapParams.fileName = argv [++i];
301 <               causticPmapParams.distribTarget =
302 <                  parseMultiplier(argv [++i]);
303 <               if (!causticPmapParams.distribTarget)
304 <                  goto badopt;
305 <            }
297 >                     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              
310 <            else if (!strcmp(argv [i] + 2, "pv")) {
311 <               /* Volume photon map */
312 <               check(4, "ss");
313 <               volumePmapParams.fileName = argv [++i];
314 <               volumePmapParams.distribTarget =
315 <                  parseMultiplier(argv [++i]);
316 <               if (!volumePmapParams.distribTarget)
317 <                  goto badopt;                      
318 <            }
319 <            
320 <            else if (!strcmp(argv [i] + 2, "pd")) {
321 <               /* Direct photon map */
322 <               check(4, "ss");
323 <               directPmapParams.fileName = argv [++i];
324 <               directPmapParams.distribTarget =
325 <                  parseMultiplier(argv [++i]);
326 <               if (!directPmapParams.distribTarget)
327 <                  goto badopt;
328 <            }
329 <            
330 <            else if (!strcmp(argv [i] + 2, "pC")) {
331 <               /* Light source contribution photon map */
332 <               check(4, "ss");
333 <               contribPmapParams.fileName = argv [++i];
334 <               contribPmapParams.distribTarget =
335 <                  parseMultiplier(argv [++i]);
336 <               if (!contribPmapParams.distribTarget)
337 <                  goto badopt;
338 <            }
310 >                     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 >                           goto badopt;
326 >                        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 <            else if (!strcmp(argv [i] + 2, "pD")) {
347 <               /* Predistribution factor */
348 <               check(4, "f");
349 <               preDistrib = atof(argv [++i]);
350 <               if (preDistrib <= 0)
351 <                  error(USER, "predistribution factor must be > 0");
258 <            }
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 <            else if (!strcmp(argv [i] + 2, "pM")) {
354 <               /* Max predistribution passes */
355 <               check(4, "i");
356 <               maxPreDistrib = atoi(argv [++i]);
357 <               if (maxPreDistrib <= 0)
358 <                  error(USER, "max predistribution passes must be > 0");
359 <            }
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 >
360   #if 1
361 <            /* Kept for backwards compat, to be phased out by -lr */
362 <            else if (!strcmp(argv [i] + 2, "pm")) {
363 <               /* Max photon bounces */
364 <               check(4, "i");              
365 <               photonMaxBounce = atol(argv [++i]);
366 <               if (photonMaxBounce <= 0)
367 <                  error(USER, "max photon bounces must be > 0");
275 <            }            
361 >                     /* 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   #endif
369 +
370   #ifdef PMAP_EKSPERTZ
371 <            /* Add region of interest; for Ze Ekspertz only! */
372 <            else if (!strcmp(argv [i] + 2, "pi")) {
373 <               unsigned j, n = pmapNumROI;
374 <               check(4, "ffffff");
375 <              
376 <               pmapROI = realloc(pmapROI,
377 <                                 ++pmapNumROI * sizeof(PhotonMapROI));
378 <               if (!pmapROI)
379 <                  error(SYSTEM, "failed to allocate ROI");
380 <                  
381 <               pmapROI [n].min [0] = atof(argv [++i]);
382 <               pmapROI [n].min [1] = atof(argv [++i]);
383 <               pmapROI [n].min [2] = atof(argv [++i]);
384 <               pmapROI [n].max [0] = atof(argv [++i]);
385 <               pmapROI [n].max [1] = atof(argv [++i]);
293 <               pmapROI [n].max [2] = atof(argv [++i]);
294 <              
295 <               for (j = 0; j < 3; j++)
296 <                  if (pmapROI [n].min [j] >= pmapROI [n].max [j])
297 <                     error(USER,
298 <                           "invalid region of interest (swapped min/max?)");
299 <            }
300 < #endif            
301 <            else if (!strcmp(argv [i] + 2, "pP")) {
302 <               /* Global photon precomputation factor */
303 <               check(4, "f");
304 <               finalGather = atof(argv [++i]);
305 <               if (finalGather <= 0 || finalGather > 1)
306 <                  error(USER, "global photon precomputation factor "
307 <                        "must be in range ]0, 1]");
308 <            }                  
309 <            
310 <            else if (!strcmp(argv [i] + 2, "po") ||
311 <                     !strcmp(argv [i] + 2, "pO")) {
312 <               /* Photon port */
313 <               check(4, "s");
314 <              
315 <               if (ambincl != 1) {
316 <                  ambincl = 1;
317 <                  portLp = amblist;
318 <               }
319 <              
320 <               if (argv[i][3] == 'O') {
321 <                  /* Get port modifiers from file */
322 <                  rval = wordfile(portLp, AMBLLEN-(portLp-amblist),
323 <                                  getpath(argv [++i], getrlibpath(), R_OK));
324 <                                  
325 <                  if (rval < 0) {
326 <                      sprintf(errmsg, "cannot open photon port file %s",
327 <                              argv [i]);
328 <                      error(SYSTEM, errmsg);
329 <                  }
330 <                  
331 <                  portLp += rval;
332 <               }
333 <              
334 <               else {
335 <                  /* Append modifier to port list */
336 <                  *portLp++ = argv [++i];
337 <                  *portLp = NULL;
338 <               }
339 <            }
340 <            
341 <            else if (!strcmp(argv [i] + 2, "pr")) {
342 <               /* Random seed */
343 <               check(4, "i");
344 <               randSeed = atoi(argv [++i]);
345 <            }                  
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 >                        n = pmapNumROI;
375 >                        
376 >                        pmapROI = realloc(
377 >                           pmapROI, ++pmapNumROI * sizeof(PhotonMapROI)
378 >                        );
379 >                        if (!pmapROI)
380 >                           error(SYSTEM, "failed to allocate ROI");
381 >                        
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 <            else if (!strcmp(argv [i] + 2, "ps") ||
388 <                     !strcmp(argv [i] + 2, "pS")) {
389 <               /* Antimatter sensor */
390 <               check(4, "s");
391 <              
392 <               if (argv[i][3] == 'S') {
393 <                  /* Get sensor modifiers from file */
394 <                  rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
395 <                                  getpath(argv [++i], getrlibpath(), R_OK));
396 <                                  
397 <                  if (rval < 0) {
398 <                      sprintf(errmsg, "cannot open antimatter sensor file %s",
399 <                              argv [i]);
400 <                      error(SYSTEM, errmsg);
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 >                        break;
418 > #endif
419 >
420 >                     case 'P': /* Global photon precomp ratio */
421 >                        check(4, "f");
422 >                        finalGather = atof(argv [++i]);
423 >                        if (finalGather <= 0 || finalGather > 1)
424 >                           error(
425 >                              USER, "global photon precomputation ratio "
426 >                              "must be in range ]0, 1]"
427 >                           );
428 >                        break;
429 >                    
430 >                     case 'o': /* Photon port */
431 >                     case 'O':
432 >                        /* 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 >                        if (isupper(argv [i][3])) {
442 >                           /* Add port modifiers from file */
443 >                           rval = wordfile(
444 >                              portLp, MAXSET - (portLp - photonPortList),
445 >                              getpath(argv [++i], getrlibpath(), R_OK)
446 >                           );
447 >                           if (rval < 0) {
448 >                               sprintf(
449 >                                  errmsg, "cannot open photon port file %s",
450 >                                  argv [i]
451 >                               );
452 >                               error(SYSTEM, errmsg);
453 >                           }
454 >                           /* 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 >                        }
469 >                        else {
470 >                           /* 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 >                           *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 >                        if (isupper(argv[i][3])) {
488 >                           /* Add sensor modifiers from file */
489 >                           rval = wordfile(
490 >                              sensLp, MAXSET - (sensLp - photonSensorList),
491 >                              getpath(argv [++i], getrlibpath(), R_OK)
492 >                           );
493 >                           if (rval < 0) {
494 >                               sprintf(
495 >                                 errmsg,
496 >                                 "cannot open antimatter sensor file %s",
497 >                                 argv [i]
498 >                              );
499 >                              error(SYSTEM, errmsg);
500 >                           }
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                    }
513 +                  break;
514                    
515 <                  sensLp += rval;
364 <               }
365 <              
366 <               else {
367 <                  /* Append modifier to sensor list */
368 <                  *sensLp++ = argv [++i];
369 <                  *sensLp = NULL;
370 <               }
515 >               default: goto badopt;
516              }
372
373            else goto badopt;                  
517              break;
518 <                  
519 <         case 'b':
518 >                
519 >         case 'b': /* Back face visibility */
520              if (argv [i][2] == 'v') {
378               /* Back face visibility */
521                 check_bool(3, backvis);
522              }
381                  
523              else goto badopt;
524              break;
525                    
# Line 403 | Line 544 | int main (int argc, char* argv [])
544              diagFile = argv [++i];
545              break;
546                    
547 <         case 'f':
547 >         case 'f': /* Force overwrite */
548              if (argv [i][2] == 'o') {
408               /* Force overwrite */
549                 check_bool(3, clobber);
550              }
411                  
551              else goto badopt;
552              break;
553 +
554   #ifdef PMAP_EKSPERTZ
555           case 'l': /* Limits */
556              switch (argv [i][2]) {
# Line 432 | Line 572 | int main (int argc, char* argv [])
572              }
573              break;
574   #endif
575 +
576           case 'm': /* Medium */
577              switch (argv[i][2]) {
578 <               case 'e':        /* Eggs-tinction coefficient */
578 >               case 'e': /* Eggs-tinction coefficient */
579                    check(3, "fff");
580 <                  setcolor(cextinction, atof(argv [i + 1]),
581 <                           atof(argv [i + 2]), atof(argv [i + 3]));
580 >                  setcolor(
581 >                     cextinction, atof(argv [i + 1]),
582 >                     atof(argv [i + 2]), atof(argv [i + 3])
583 >                  );
584                    i += 3;
585                    break;
586                                  
587                 case 'a':        /* Albedo */
588                    check(3, "fff");
589 <                  setcolor(salbedo, atof(argv [i + 1]),
590 <                           atof(argv [i + 2]), atof(argv [i + 3]));
589 >                  setcolor(
590 >                     salbedo, atof(argv [i + 1]),
591 >                     atof(argv [i + 2]), atof(argv [i + 3])
592 >                  );
593                    i += 3;
594                    break;
595                                  
# Line 456 | Line 601 | int main (int argc, char* argv [])
601                 default: goto badopt;
602              }                  
603              break;
604 +            
605   #if NIX
606           case 'n': /* Num parallel processes (NIX only) */
607              check(2, "i");
# Line 463 | Line 609 | int main (int argc, char* argv [])
609              
610              if (nproc > PMAP_MAXPROC) {
611                 nproc = PMAP_MAXPROC;
612 <               sprintf(errmsg, "too many parallel processes, clamping to "
613 <                       "%d\n", nproc);
612 >               sprintf(
613 >                  errmsg, "too many parallel processes, clamping to %d\n",
614 >                  nproc
615 >               );
616                 error(WARNING, errmsg);
617 <            }            
618 <            break;                  
619 < #endif                        
617 >            }
618 >            break;
619 > #endif
620 >
621           case 't': /* Timer */
622              check(2, "i");
623              photonRepTime = atoi(argv [++i]);
# Line 476 | Line 625 | int main (int argc, char* argv [])
625              
626           case 'v':   /* Verbosity */
627              check_bool(2, verbose);
628 <            break;            
628 >            break;
629 >            
630   #ifdef EVALDRC_HACK
631           case 'A':   /* Angular source file */
632              check(2,"s");
633              angsrcfile = argv[++i];
634 <            break;                  
635 < #endif                              
636 <         default: goto badopt;
634 >            break;
635 > #endif
636 >
637 >        default: goto badopt;
638        }
639     }
640    
641     /* Open diagnostics file */
642     if (diagFile) {
643 <      if (!freopen(diagFile, "a", stderr)) quit(2);
643 >      if (!freopen(diagFile, "a", stderr))
644 >         quit(2);
645        fprintf(stderr, "**************\n*** PID %5d: ", getpid());
646        printargs(argc, argv, stderr);
647        putc('\n', stderr);
# Line 509 | Line 661 | int main (int argc, char* argv [])
661        setPmapParam(photonMaps + i, pmapParams + i);
662        
663        /* Don't overwrite existing photon map unless clobbering enabled */
664 <      if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
665 <          !clobber) {
666 <         sprintf(errmsg, "photon map file %s exists, not overwritten",
667 <                 photonMaps [i] -> fileName);
664 >      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           error(USER, errmsg);
673        }
674     }
675        
676 <   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);  
676 >   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);
677     if (i >= NUM_PMAP_TYPES)
678        error(USER, "no photon maps specified");
679    
# Line 552 | Line 708 | badopt:
708     #undef check_bool
709     return 0;
710   }
711 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines