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.6 by rschregle, Mon Aug 14 21:12:10 2017 UTC vs.
Revision 2.13 by greg, Wed Apr 23 02:13:34 2025 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 "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  
# Line 45 | Line 57 | int      clobber = 0;               /* overwrite outpu
57   COLOR    cextinction = BLKCOLOR;    /* global extinction coefficient */
58   COLOR    salbedo = BLKCOLOR;        /* global scattering albedo */
59   double   seccg = 0;                 /* global scattering eccentricity */
60 < int      ambincl = -1;              /* photon port flag */
61 < char     *amblist [AMBLLEN + 1];    /* photon port list */
60 > char     *amblist [AMBLLEN + 1];    /* ambient include/exclude list */
61 > int      ambincl = -1;              /* include == 1, exclude == 0 */
62   char     *diagFile = NULL;          /* diagnostics output file */
63   int      rand_samp = 1;             /* uncorrelated random sampling */
64   unsigned nproc = 1;                 /* number of parallel processes */
# Line 58 | Line 70 | unsigned nproc = 1;                 /* number of paral
70   /* Dummies for linkage */
71  
72   COLOR ambval = BLKCOLOR;
73 < double shadthresh = .05, ambacc = 0.2, shadcert = .5, minweight = 5e-3,
74 <       ssampdist = 0, dstrsrc = 0.0, specthresh = 0.15, specjitter = 1.0,
75 <       avgrefl = 0.5;    
76 < int ambvwt = 0, ambssamp = 0, ambres = 32, ambounce = 0, directrelay = 1,
77 <    directvis = 1, samplendx, do_irrad = 0, ambdiv = 128, vspretest = 512,
78 <    maxdepth = 6, contrib = 0;
79 < char *shm_boundary = NULL, *ambfile = NULL, *RCCONTEXT = NULL;
80 < void (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
73 > double   shadthresh = .05, ambacc = 0.2, shadcert = .5, minweight = 5e-3,
74 >         ssampdist = 0, dstrsrc = 0.0, specthresh = 0.15, specjitter = 1.0,
75 >         avgrefl = 0.5;
76 > int      ambvwt = 0, ambssamp = 0, ambres = 32, ambounce = 0,
77 >         directrelay = 1, directvis = 1, samplendx, do_irrad = 0,
78 >         ambdiv = 128, vspretest = 512, maxdepth = 6, contrib = 0;
79 > char     *ambfile = NULL, *RCCONTEXT = NULL;
80 > void     (*trace)() = NULL, (*addobjnotify [])() = {ambnotify, NULL};
81  
82    
83   void printdefaults()
84   /* print default values to stdout */
85   {
74   puts("-apg file nPhotons\t\t# global photon map");
75   puts("-apc file nPhotons\t\t# caustic photon map");          
76   puts("-apd file nPhotons\t\t# direct photon map");
77   puts("-app file nPhotons bwidth\t# precomputed global photon map");
78   puts("-apv file nPhotons\t\t# volume photon map");
79   puts("-apC file nPhotons\t\t# contribution photon map");
80  
81   printf("-apD %f\t\t\t# predistribution factor\n", preDistrib);
82   printf("-apM %d\t\t\t\t# max predistrib passes\n", maxPreDistrib);
83   printf("-apm %ld\t\t\t# max photon bounces\n", photonMaxBounce);                            
84   puts("-apo mod\t\t\t# photon port modifier");
85   puts("-apO file\t\t\t# photon port file");
86   printf("-apP %f\t\t\t# precomputation factor\n", finalGather);
87   printf("-apr %d\t\t\t\t# random seed\n", randSeed);
88   puts("-aps mod\t\t\t# antimatter sensor modifier");
89   puts("-apS file\t\t\t# antimatter sensor file");
90
91   printf(backvis ? "-bv+\t\t\t\t# back face visibility on\n"
92                  : "-bv-\t\t\t\t# back face visibility off\n");
93   printf("-dp  %.1f\t\t\t# PDF samples / sr\n", pdfSamples);
94   printf("-ds  %f\t\t\t# source partition size ratio\n", srcsizerat);
95   printf("-e   %s\t\t\t# diagnostics output file\n", diagFile);
96   printf(clobber ? "-fo+\t\t\t\t# force overwrite\n"
97                  : "-fo-\t\t\t\t# do not overwrite\n");
98   printf("-ma  %.2f %.2f %.2f\t\t# scattering albedo\n",
99          colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU));
100   printf("-me  %.2e %.2e %.2e\t# extinction coefficient\n",
101          colval(cextinction,RED), colval(cextinction,GRN),
102          colval(cextinction,BLU));          
103   printf("-mg  %.2f\t\t\t# scattering eccentricity\n", seccg);
104 #if NIX  
105   /* Multiprocessing on NIX only */
106   printf("-n   %d\t\t\t\t# number of parallel processes\n", nproc);
107 #endif  
108   printf("-t   %-9d\t\t\t# time between reports\n", photonRepTime);
109   printf(verbose ? "-v+\t\t\t\t# verbose console output\n"
110                  : "-v-\t\t\t\t# terse console output\n");
111 #ifdef PMAP_ROI
112   /* Ziss option for ze egg-spurtz only! */
113   puts("-api xmin ymin zmin\n     xmax ymax zmax\t\t# region of interest");
114 #endif  
86   #ifdef EVALDRC_HACK
87 <   /* ... and ziss one... */
87 >   /* EvalDRC support */
88     puts("-A\t\t\t\t# angular source file");
89 + #endif    
90 +   puts("-ae  mod\t\t\t\t# exclude modifier");
91 +   puts("-aE  file\t\t\t\t# exclude modifiers from file");
92 +   puts("-ai  mod\t\t\t\t# include modifier");
93 +   puts("-aI  file\t\t\t\t# include modifiers from file");
94 + #ifdef PMAP_EKSPERTZ
95 +   puts("-api xmin ymin zmin xmax ymax zmax\t# rectangular region of interest");
96 +   puts("-apI xpos ypos zpos radius\t\t# spherical region of interest");
97   #endif
98 +   puts("-apg file nPhotons\t\t\t# global photon map");
99 +   puts("-apc file nPhotons\t\t\t# caustic photon map");
100 +   puts("-apd file nPhotons\t\t\t# direct photon map");
101 +   puts("-app file nPhotons bwidth\t\t# precomputed global photon map");
102 +   puts("-apv file nPhotons\t\t\t# volume photon map");
103 +   puts("-apC file nPhotons\t\t\t# contribution photon map");  
104 +   printf("-apD %f\t\t\t\t# predistribution factor\n", preDistrib);
105 +   printf("-apM %d\t\t\t\t\t# max predistrib passes\n", maxPreDistrib);
106 + #if 1
107 +   /* Kept for backwards compat, will be gradually phased out by -ld, -lr */
108 +   printf("-apm %ld\t\t\t\t# limit photon bounces\n", photonMaxBounce);
109 + #endif
110 +   puts("-apo+ mod\t\t\t\t# photon port modifier");
111 +   puts("-apO+ file\t\t\t\t# photon ports from file");
112 +   printf("-apP %f\t\t\t\t# precomputation factor\n", finalGather);
113 +   printf("-apr %d\t\t\t\t\t# random seed\n", randSeed);
114 +   puts("-aps mod\t\t\t\t# antimatter sensor modifier");
115 +   puts("-apS file\t\t\t\t# antimatter sensors from file");
116 +
117 +   printf(backvis
118 +      ? "-bv+\t\t\t\t\t# back face visibility on\n"
119 +      : "-bv-\t\t\t\t\t# back face visibility off\n"
120 +   );
121 +   printf("-dp  %.1f\t\t\t\t# PDF samples / sr\n", pdfSamples);
122 +   printf("-ds  %f\t\t\t\t# source partition size ratio\n", srcsizerat);
123 +   printf("-e   %s\t\t\t\t# diagnostics output file\n", diagFile);
124 +   printf(clobber
125 +      ?  "-fo+\t\t\t\t\t# force overwrite\n"
126 +      :  "-fo-\t\t\t\t\t# do not overwrite\n"
127 +   );
128 + #ifdef PMAP_EKSPERTZ
129 +   /* (Formerly) NU STUFF for Ze Exspertz! */      
130 +   printf("-ld %.1f\t\t\t\t\t# limit photon distance\n", photonMaxDist);
131 +   printf("-lr %ld\t\t\t\t# limit photon bounces\n", photonMaxBounce);  
132 + #endif  
133 +   printf(
134 +      "-ma  %.2f %.2f %.2f\t\t\t# scattering albedo\n",
135 +      colval(salbedo,RED), colval(salbedo,GRN), colval(salbedo,BLU)
136 +   );
137 +   printf(
138 +      "-me  %.2e %.2e %.2e\t\t# extinction coefficient\n",
139 +      colval(cextinction,RED), colval(cextinction,GRN),
140 +      colval(cextinction,BLU)
141 +   );
142 +   printf("-mg  %.2f\t\t\t\t# scattering eccentricity\n", seccg);
143 + #if NIX  
144 +   /* Multiprocessing on NIX only; so tuff luck, Windoze Weenies! */
145 +   printf("-n   %d\t\t\t\t\t# number of parallel processes\n", nproc);
146 + #endif  
147 +   printf("-t   %-9d\t\t\t\t# time between reports\n", photonRepTime);
148 +   printf(verbose
149 +      ?  "-v+\t\t\t\t\t# verbose console output\n"
150 +      :  "-v-\t\t\t\t\t# terse console output\n"
151 +   );
152   }
153  
154  
155   int main (int argc, char* argv [])
156   {
157 <   #define check(ol, al) if (argv [i][ol] || \
158 <                             badarg(argc - i - 1,argv + i + 1, al)) \
159 <                            goto badopt
160 <                            
157 >   #define check(ol, al) if ( \
158 >      argv [i][ol] || badarg(argc - i - 1,argv + i + 1, al) \
159 >   ) goto badopt
160 >  
161 >   /* Evaluate boolean option, setting var accordingly */                        
162     #define check_bool(olen, var) switch (argv [i][olen]) { \
163 <                             case '\0': var = !var; break; \
164 <                             case 'y': case 'Y': case 't': case 'T': \
165 <                             case '+': case '1': var = 1; break; \
166 <                             case 'n': case 'N': case 'f': case 'F': \
167 <                             case '-': case '0': var = 0; break; \
168 <                             default: goto badopt; \
169 <                          }  
163 >      case '\0': \
164 >         var = !var; break; \
165 >      case 'y': case 'Y': case 't': case 'T': case '+': case '1': \
166 >         var = 1; break; \
167 >      case 'n': case 'N': case 'f': case 'F': case '-': case '0': \
168 >         var = 0; break; \
169 >      default: \
170 >         goto badopt; \
171 >   }
172 >  
173 >   /* Evaluate trinary option, setting bits v1 and v2 in var accordingly */
174 >   #define check_tri(olen, v1, v2, var) switch (argv [i][olen]) { \
175 >      case '\0': case '+': \
176 >         var = v1; break; \
177 >      case '-': \
178 >         var = v2; break;\
179 >      case '0': \
180 >         var = v1 | v2; break; \
181 >      default: \
182 >         goto badopt; \
183 >   }
184  
185 <   int loadflags = IO_CHECK | IO_SCENE | IO_TREE | IO_BOUNDS, rval, i;
186 <   char **portLp = NULL, **sensLp = photonSensorList;
187 <   struct stat pmstat;
185 >   int      loadflags = IO_CHECK | IO_SCENE | IO_TREE | IO_BOUNDS,
186 >            rval, i, j, n;
187 >   char     **portLp = photonPortList, **sensLp = photonSensorList,
188 >            **amblp = NULL, sbuf [MAXSTR], portFlags [2] = "\0\0";
189 >   struct   stat pmstat;
190  
191     /* Global program name */
192     progname = fixargv0(argv [0]);
193     /* Initialize object types */
194     initotypes();
195 <  
195 >   /* initialize calcomp routines */
196 >   initfunc();
197 >
198     /* Parse options */
199     for (i = 1; i < argc; i++) {
200        /* Eggs-pand arguments */
# Line 172 | Line 224 | int main (int argc, char* argv [])
224        }
225              
226        switch (argv [i][1]) {
227 <         case 'a':
228 <            if (!strcmp(argv [i] + 2, "pg")) {
229 <               /* Global photon map */
230 <               check(4, "ss");
231 <               globalPmapParams.fileName = argv [++i];
232 <               globalPmapParams.distribTarget =
233 <                  parseMultiplier(argv [++i]);
234 <               if (!globalPmapParams.distribTarget)
235 <                  goto badopt;                        
236 <               globalPmapParams.minGather = globalPmapParams.maxGather = 0;
237 <            }
238 <                              
239 <            else if (!strcmp(argv [i] + 2, "pm")) {
240 <               /* Max photon bounces */
241 <               check(4, "i");              
242 <               photonMaxBounce = atol(argv [++i]);
243 <               if (photonMaxBounce <= 0)
244 <                  error(USER, "max photon bounces must be > 0");
245 <            }
227 >         case 'a': /* Ambient */
228 >            switch (argv [i][2]) {
229 >               case 'i': /* Ambient include */
230 >               case 'I':
231 >                  check(3, "s");
232 >                  if (ambincl != 1) {
233 >                     ambincl = 1;
234 >                     amblp = amblist;
235 >                  }
236 >                  if (isupper(argv [i][2])) {
237 >                     /* Add modifiers from file */
238 >                     rval = wordfile(
239 >                        amblp, AMBLLEN - (amblp - amblist),
240 >                        getpath(argv [++i], getrlibpath(), R_OK)
241 >                     );
242 >                     if (rval < 0) {
243 >                        sprintf(
244 >                           errmsg, "cannot open ambient include file \"%s\"",
245 >                           argv [i]
246 >                        );
247 >                        error(SYSTEM, errmsg);
248 >                     }
249 >                     amblp += rval;
250 >                  }
251 >                  else {
252 >                     /* Add modifier from next arg */
253 >                     *amblp++ = savqstr(argv [++i]);
254 >                     *amblp = NULL;
255 >                  }
256 >                  break;
257 >
258 >               case 'e': /* Ambient exclude */
259 >               case 'E':
260 >                  check(3, "s");
261 >                  if (ambincl != 0) {
262 >                     ambincl = 0;
263 >                     amblp = amblist;
264 >                  }
265 >                  if (isupper(argv [i][2])) {
266 >                     /* Add modifiers from file */
267 >                     rval = wordfile(
268 >                        amblp, AMBLLEN - (amblp - amblist),
269 >                        getpath(argv [++i], getrlibpath(), R_OK)
270 >                     );
271 >                     if (rval < 0) {
272 >                        sprintf(
273 >                           errmsg, "cannot open ambient exclude file \"%s\"",
274 >                           argv [i]
275 >                        );
276 >                        error(SYSTEM, errmsg);
277 >                     }
278 >                     amblp += rval;
279 >                  }
280 >                  else {
281 >                     /* Add modifier from next arg */
282 >                     *amblp++ = savqstr(argv [++i]);
283 >                     *amblp = NULL;
284 >                  }
285 >                  break;
286              
287 <            else if (!strcmp(argv [i] + 2, "pp")) {
288 <               /* Precomputed global photon map */
289 <               check(4, "ssi");
290 <               preCompPmapParams.fileName = argv [++i];
291 <               preCompPmapParams.distribTarget =
292 <                  parseMultiplier(argv [++i]);
293 <               if (!preCompPmapParams.distribTarget)
294 <                  goto badopt;
295 <               preCompPmapParams.minGather = preCompPmapParams.maxGather =
296 <                  atoi(argv [++i]);
297 <               if (!preCompPmapParams.maxGather)
298 <                  goto badopt;
207 <            }
287 >               case 'p': /* Pmap-specific */
288 >                  switch (argv [i][3]) {
289 >                     case 'g': /* Global photon map */
290 >                        check(4, "ss");
291 >                        globalPmapParams.fileName = argv [++i];
292 >                        globalPmapParams.distribTarget =
293 >                           parseMultiplier(argv [++i]);
294 >                        if (!globalPmapParams.distribTarget)
295 >                           goto badopt;
296 >                        globalPmapParams.minGather =
297 >                           globalPmapParams.maxGather = 0;
298 >                        break;
299              
300 <            else if (!strcmp(argv [i] + 2, "pc")) {
301 <               /* Caustic photon map */
302 <               check(4, "ss");
303 <               causticPmapParams.fileName = argv [++i];
304 <               causticPmapParams.distribTarget =
305 <                  parseMultiplier(argv [++i]);
306 <               if (!causticPmapParams.distribTarget)
307 <                  goto badopt;
308 <            }
300 >                     case 'p': /* Precomputed global photon map */
301 >                        check(4, "ssi");
302 >                        preCompPmapParams.fileName = argv [++i];
303 >                        preCompPmapParams.distribTarget =
304 >                           parseMultiplier(argv [++i]);
305 >                        if (!preCompPmapParams.distribTarget)
306 >                           goto badopt;
307 >                        preCompPmapParams.minGather =
308 >                           preCompPmapParams.maxGather = atoi(argv [++i]);
309 >                        if (!preCompPmapParams.maxGather)
310 >                           goto badopt;
311 >                        break;
312              
313 <            else if (!strcmp(argv [i] + 2, "pv")) {
314 <               /* Volume photon map */
315 <               check(4, "ss");
316 <               volumePmapParams.fileName = argv [++i];
317 <               volumePmapParams.distribTarget =
318 <                  parseMultiplier(argv [++i]);
319 <               if (!volumePmapParams.distribTarget)
320 <                  goto badopt;                      
227 <            }
228 <            
229 <            else if (!strcmp(argv [i] + 2, "pd")) {
230 <               /* Direct photon map */
231 <               check(4, "ss");
232 <               directPmapParams.fileName = argv [++i];
233 <               directPmapParams.distribTarget =
234 <                  parseMultiplier(argv [++i]);
235 <               if (!directPmapParams.distribTarget)
236 <                  goto badopt;
237 <            }
238 <            
239 <            else if (!strcmp(argv [i] + 2, "pC")) {
240 <               /* Light source contribution photon map */
241 <               check(4, "ss");
242 <               contribPmapParams.fileName = argv [++i];
243 <               contribPmapParams.distribTarget =
244 <                  parseMultiplier(argv [++i]);
245 <               if (!contribPmapParams.distribTarget)
246 <                  goto badopt;
247 <            }
248 <            
249 <            else if (!strcmp(argv [i] + 2, "pD")) {
250 <               /* Predistribution factor */
251 <               check(4, "f");
252 <               preDistrib = atof(argv [++i]);
253 <               if (preDistrib <= 0)
254 <                  error(USER, "predistribution factor must be > 0");
255 <            }
256 <            
257 <            else if (!strcmp(argv [i] + 2, "pM")) {
258 <               /* Max predistribution passes */
259 <               check(4, "i");
260 <               maxPreDistrib = atoi(argv [++i]);
261 <               if (maxPreDistrib <= 0)
262 <                  error(USER, "max predistribution passes must be > 0");
263 <            }
264 <
265 < #ifdef PMAP_ROI
266 <            /* Add region of interest; for ze egg-spurtz only! */
267 <            else if (!strcmp(argv [i] + 2, "pi")) {
268 <               unsigned j, n = pmapNumROI;
269 <               check(4, "ffffff");
270 <              
271 <               pmapROI = realloc(pmapROI,
272 <                                 ++pmapNumROI * sizeof(PhotonMapROI));
273 <               if (!pmapROI)
274 < 1                  error(SYSTEM, "failed to allocate ROI");
313 >                     case 'c': /* 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 >                        break;
321                    
322 <               pmapROI [n].min [0] = atof(argv [++i]);
323 <               pmapROI [n].min [1] = atof(argv [++i]);
324 <               pmapROI [n].min [2] = atof(argv [++i]);
325 <               pmapROI [n].max [0] = atof(argv [++i]);
326 <               pmapROI [n].max [1] = atof(argv [++i]);
327 <               pmapROI [n].max [2] = atof(argv [++i]);
328 <              
329 <               for (j = 0; j < 3; j++)
330 <                  if (pmapROI [n].min [j] >= pmapROI [n].max [j])
331 <                     error(USER,
332 <                           "invalid region of interest (swapped min/max?)");
333 <            }
322 >                     case 'v': /* Volume photon map */
323 >                        check(4, "ss");
324 >                        volumePmapParams.fileName = argv [++i];
325 >                        volumePmapParams.distribTarget =
326 >                           parseMultiplier(argv [++i]);
327 >                        if (!volumePmapParams.distribTarget)
328 >                           goto badopt;
329 >                        break;
330 >                    
331 >                     case 'd': /* Direct photon map */
332 >                        check(4, "ss");
333 >                        directPmapParams.fileName = argv [++i];
334 >                        directPmapParams.distribTarget =
335 >                           parseMultiplier(argv [++i]);
336 >                        if (!directPmapParams.distribTarget)
337 >                           goto badopt;
338 >                        break;
339 >                    
340 >                     case 'C': /* Contribution photon map */
341 >                        check(4, "ss");
342 >                        contribPmapParams.fileName = argv [++i];
343 >                        contribPmapParams.distribTarget =
344 >                           parseMultiplier(argv [++i]);
345 >                        if (!contribPmapParams.distribTarget)
346 >                           goto badopt;
347 >                        break;
348 >
349 >                     case 'D': /* Predistribution factor */
350 >                        check(4, "f");
351 >                        preDistrib = atof(argv [++i]);
352 >                        if (preDistrib <= 0)
353 >                           error(USER, "predistrib factor must be > 0");
354 >                        break;
355 >
356 >                     case 'M': /* Max predistribution passes */
357 >                        check(4, "i");
358 >                        maxPreDistrib = atoi(argv [++i]);
359 >                        if (maxPreDistrib <= 0)
360 >                           error(USER, "max predistrib passes must be > 0");
361 >                        break;
362 >
363 > #if 1
364 >                     /* Kept for backwards compat, to be phased out by -lr */
365 >                     case 'm': /* Max photon bounces */
366 >                        check(4, "i");
367 >                        photonMaxBounce = atol(argv [++i]);
368 >                        if (photonMaxBounce <= 0)
369 >                           error(USER, "max photon bounces must be > 0");
370 >                        break;
371   #endif
289            
290            else if (!strcmp(argv [i] + 2, "pP")) {
291               /* Global photon precomputation factor */
292               check(4, "f");
293               finalGather = atof(argv [++i]);
294               if (finalGather <= 0 || finalGather > 1)
295                  error(USER, "global photon precomputation factor "
296                        "must be in range ]0, 1]");
297            }                  
298            
299            else if (!strcmp(argv [i] + 2, "po") ||
300                     !strcmp(argv [i] + 2, "pO")) {
301               /* Photon port */
302               check(4, "s");
303              
304               if (ambincl != 1) {
305                  ambincl = 1;
306                  portLp = amblist;
307               }
308              
309               if (argv[i][3] == 'O') {
310                  /* Get port modifiers from file */
311                  rval = wordfile(portLp, AMBLLEN-(portLp-amblist),
312                                  getpath(argv [++i], getrlibpath(), R_OK));
313                                  
314                  if (rval < 0) {
315                      sprintf(errmsg, "cannot open photon port file %s",
316                              argv [i]);
317                      error(SYSTEM, errmsg);
318                  }
319                  
320                  portLp += rval;
321               }
322              
323               else {
324                  /* Append modifier to port list */
325                  *portLp++ = argv [++i];
326                  *portLp = NULL;
327               }
328            }
329            
330            else if (!strcmp(argv [i] + 2, "pr")) {
331               /* Random seed */
332               check(4, "i");
333               randSeed = atoi(argv [++i]);
334            }                  
372  
373 <            else if (!strcmp(argv [i] + 2, "ps") ||
374 <                     !strcmp(argv [i] + 2, "pS")) {
375 <               /* Antimatter sensor */
376 <               check(4, "s");
377 <              
378 <               if (argv[i][3] == 'S') {
379 <                  /* Get sensor modifiers from file */
380 <                  rval = wordfile(sensLp, MAXSET-(sensLp-photonSensorList),
381 <                                  getpath(argv [++i], getrlibpath(), R_OK));
382 <                                  
383 <                  if (rval < 0) {
384 <                      sprintf(errmsg, "cannot open antimatter sensor file %s",
385 <                              argv [i]);
386 <                      error(SYSTEM, errmsg);
373 > #ifdef PMAP_EKSPERTZ
374 >                     case 'i': /* Add rectangular region of interest */
375 >                     case 'I': /* Add spherical region of interest */
376 >                        check(4, isupper(argv [j=i][3]) ? "ffff" : "ffffff");
377 >                        n = pmapNumROI;
378 >                        
379 >                        pmapROI = realloc(
380 >                           pmapROI, ++pmapNumROI * sizeof(PhotonMapROI)
381 >                        );
382 >                        if (!pmapROI)
383 >                           error(SYSTEM, "failed to allocate ROI");
384 >                        
385 >                        pmapROI [n].pos [0] = atof(argv [++i]);
386 >                        pmapROI [n].pos [1] = atof(argv [++i]);
387 >                        pmapROI [n].pos [2] = atof(argv [++i]);
388 >                        pmapROI [n].siz [0] = atof(argv [++i]);
389 >
390 >                        if (isupper(argv [j][3])) {
391 >                           /* Spherical ROI; radius^2 */
392 >                           pmapROI [n].siz [0] *= pmapROI [n].siz [0];
393 >                           PMAP_ROI_SETSPHERE(pmapROI + n);
394 >                           if (pmapROI [n].siz [0] <= FTINY)
395 >                              error(
396 >                                 USER,
397 >                                 "region of interest has invalid radius"
398 >                              );
399 >                        }
400 >                        else {
401 >                           /* Rectangular ROI */
402 >                           pmapROI [n].siz [1] = atof(argv [++i]);
403 >                           pmapROI [n].siz [2] = atof(argv [++i]);
404 >
405 >                           for (j = 0; j < 3; j++) {
406 >                              /* Pos at rectangle centre, siz symmetric */
407 >                              pmapROI [n].pos [j] = 0.5 * (
408 >                                 pmapROI [n].pos [j] + pmapROI [n].siz [j]
409 >                              );
410 >                              pmapROI [n].siz [j] = fabs(
411 >                                 pmapROI [n].siz [j] - pmapROI [n].pos [j]
412 >                              );
413 >                              if (pmapROI [n].siz [j] <= FTINY)
414 >                                 error(
415 >                                    USER,
416 >                                    "region of interest has invalid size"
417 >                                 );
418 >                           }
419 >                        }
420 >                        break;
421 > #endif
422 >
423 >                     case 'P': /* Global photon precomp ratio */
424 >                        check(4, "f");
425 >                        finalGather = atof(argv [++i]);
426 >                        if (finalGather <= 0 || finalGather > 1)
427 >                           error(
428 >                              USER, "global photon precomputation ratio "
429 >                              "must be in range ]0, 1]"
430 >                           );
431 >                        break;
432 >                    
433 >                     case 'o': /* Photon port */
434 >                     case 'O':
435 >                        /* Check for bad arg and length, taking into account
436 >                         * default forward orientation if none specified, in
437 >                         * order to maintain previous behaviour */
438 >                        check(argv [i][4] ? 5 : 4, "s");
439 >                        /* Get port orientation flags */
440 >                        check_tri(
441 >                           4, PMAP_PORTFWD, PMAP_PORTBWD, portFlags [0]
442 >                        );
443 >                        
444 >                        if (isupper(argv [i][3])) {
445 >                           /* Add port modifiers from file */
446 >                           rval = wordfile(
447 >                              portLp, MAXSET - (portLp - photonPortList),
448 >                              getpath(argv [++i], getrlibpath(), R_OK)
449 >                           );
450 >                           if (rval < 0) {
451 >                               sprintf(
452 >                                  errmsg, "cannot open photon port file %s",
453 >                                  argv [i]
454 >                               );
455 >                               error(SYSTEM, errmsg);
456 >                           }
457 >                           /* HACK: append port orientation flags to every
458 >                            * modifier; note this requires reallocation */
459 >                           for (; rval--; portLp++) {
460 >                              j = strlen(*portLp);
461 >                              if (!(*portLp = realloc(*portLp, j + 2))) {
462 >                                  sprintf(
463 >                                     errmsg,
464 >                                     "cannot allocate photon port modifiers"
465 >                                     " from file %s", argv [i]
466 >                                  );
467 >                                  error(SYSTEM, errmsg);
468 >                              }
469 >                              strcat(*portLp, portFlags);
470 >                           }
471 >                        }
472 >                        else {
473 >                           /* Append port flags to port modifier, add to
474 >                            * port list and mark of end list with NULL */
475 >                           strcpy(sbuf, argv [++i]);
476 >                           strcat(sbuf, portFlags);
477 >                           *portLp++ = savqstr(sbuf);
478 >                           *portLp = NULL;
479 >                        }
480 >                        break;
481 >                    
482 >                     case 'r': /* Random seed */
483 >                        check(4, "i");
484 >                        randSeed = atoi(argv [++i]);
485 >                        break;                  
486 >
487 >                     case 's': /* Antimatter sensor */
488 >                     case 'S':
489 >                        check(4, "s");
490 >                        if (isupper(argv[i][3])) {
491 >                           /* Add sensor modifiers from file */
492 >                           rval = wordfile(
493 >                              sensLp, MAXSET - (sensLp - photonSensorList),
494 >                              getpath(argv [++i], getrlibpath(), R_OK)
495 >                           );
496 >                           if (rval < 0) {
497 >                               sprintf(
498 >                                 errmsg,
499 >                                 "cannot open antimatter sensor file %s",
500 >                                 argv [i]
501 >                              );
502 >                              error(SYSTEM, errmsg);
503 >                           }
504 >                           sensLp += rval;
505 >                        }
506 >                        else {
507 >                           /* Append modifier to sensor list, mark end with
508 >                            * NULL */
509 >                           *sensLp++ = savqstr(argv [++i]);
510 >                           *sensLp = NULL;
511 >                        }
512 >                        break;
513 >
514 >                     default: goto badopt;
515                    }
516 +                  break;
517                    
518 <                  sensLp += rval;
353 <               }
354 <              
355 <               else {
356 <                  /* Append modifier to sensor list */
357 <                  *sensLp++ = argv [++i];
358 <                  *sensLp = NULL;
359 <               }
518 >               default: goto badopt;
519              }
361
362            else goto badopt;                  
520              break;
521 <                  
522 <         case 'b':
521 >                
522 >         case 'b': /* Back face visibility */
523              if (argv [i][2] == 'v') {
367               /* Back face visibility */
524                 check_bool(3, backvis);
525              }
370                  
526              else goto badopt;
527              break;
528                    
# Line 392 | Line 547 | int main (int argc, char* argv [])
547              diagFile = argv [++i];
548              break;
549                    
550 <         case 'f':
550 >         case 'f': /* Force overwrite */
551              if (argv [i][2] == 'o') {
397               /* Force overwrite */
552                 check_bool(3, clobber);
553              }
400                  
554              else goto badopt;
555              break;
556  
557 + #ifdef PMAP_EKSPERTZ
558 +         case 'l': /* Limits */
559 +            switch (argv [i][2]) {
560 +               case 'd': /* Limit photon path distance */
561 +                  check(3, "f");
562 +                  photonMaxDist = atof(argv [++i]);
563 +                  if (photonMaxDist <= 0)
564 +                     error(USER, "max photon distance must be > 0");
565 +                  break;
566 +                
567 +               case 'r': /* Limit photon bounces */              
568 +                  check(3, "i");              
569 +                  photonMaxBounce = atol(argv [++i]);
570 +                  if (photonMaxBounce <= 0)
571 +                     error(USER, "max photon bounces must be > 0");
572 +                  break;
573 +              
574 +               default: goto badopt;
575 +            }
576 +            break;
577 + #endif
578 +
579           case 'm': /* Medium */
580              switch (argv[i][2]) {
581 <               case 'e':        /* Eggs-tinction coefficient */
581 >               case 'e': /* Eggs-tinction coefficient */
582                    check(3, "fff");
583 <                  setcolor(cextinction, atof(argv [i + 1]),
584 <                           atof(argv [i + 2]), atof(argv [i + 3]));
583 >                  setcolor(
584 >                     cextinction, atof(argv [i + 1]),
585 >                     atof(argv [i + 2]), atof(argv [i + 3])
586 >                  );
587                    i += 3;
588                    break;
589                                  
590                 case 'a':        /* Albedo */
591                    check(3, "fff");
592 <                  setcolor(salbedo, atof(argv [i + 1]),
593 <                           atof(argv [i + 2]), atof(argv [i + 3]));
592 >                  setcolor(
593 >                     salbedo, atof(argv [i + 1]),
594 >                     atof(argv [i + 2]), atof(argv [i + 3])
595 >                  );
596                    i += 3;
597                    break;
598                                  
# Line 425 | Line 604 | int main (int argc, char* argv [])
604                 default: goto badopt;
605              }                  
606              break;
607 +            
608   #if NIX
609           case 'n': /* Num parallel processes (NIX only) */
610              check(2, "i");
# Line 432 | Line 612 | int main (int argc, char* argv [])
612              
613              if (nproc > PMAP_MAXPROC) {
614                 nproc = PMAP_MAXPROC;
615 <               sprintf(errmsg, "too many parallel processes, clamping to "
616 <                       "%d\n", nproc);
615 >               sprintf(
616 >                  errmsg, "too many parallel processes, clamping to %d\n",
617 >                  nproc
618 >               );
619                 error(WARNING, errmsg);
620 <            }            
621 <            break;                  
622 < #endif                        
620 >            }
621 >            break;
622 > #endif
623 >
624           case 't': /* Timer */
625              check(2, "i");
626              photonRepTime = atoi(argv [++i]);
# Line 445 | Line 628 | int main (int argc, char* argv [])
628              
629           case 'v':   /* Verbosity */
630              check_bool(2, verbose);
631 <            break;            
631 >            break;
632 >            
633   #ifdef EVALDRC_HACK
634           case 'A':   /* Angular source file */
635              check(2,"s");
636              angsrcfile = argv[++i];
637 <            break;                  
638 < #endif                              
639 <         default: goto badopt;
637 >            break;
638 > #endif
639 >
640 >        default: goto badopt;
641        }
642     }
643    
644     /* Open diagnostics file */
645     if (diagFile) {
646 <      if (!freopen(diagFile, "a", stderr)) quit(2);
646 >      if (!freopen(diagFile, "a", stderr))
647 >         quit(2);
648        fprintf(stderr, "**************\n*** PID %5d: ", getpid());
649        printargs(argc, argv, stderr);
650        putc('\n', stderr);
# Line 478 | Line 664 | int main (int argc, char* argv [])
664        setPmapParam(photonMaps + i, pmapParams + i);
665        
666        /* Don't overwrite existing photon map unless clobbering enabled */
667 <      if (photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
668 <          !clobber) {
669 <         sprintf(errmsg, "photon map file %s exists, not overwritten",
670 <                 photonMaps [i] -> fileName);
667 >      if (
668 >         photonMaps [i] && !stat(photonMaps [i] -> fileName, &pmstat) &&
669 >         !clobber
670 >      ) {
671 >         sprintf(
672 >            errmsg, "photon map file %s exists, not overwritten",
673 >           photonMaps [i] -> fileName
674 >         );
675           error(USER, errmsg);
676        }
677     }
678        
679 <   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);  
679 >   for (i = 0; i < NUM_PMAP_TYPES && !photonMaps [i]; i++);
680     if (i >= NUM_PMAP_TYPES)
681        error(USER, "no photon maps specified");
682    
# Line 521 | Line 711 | badopt:
711     #undef check_bool
712     return 0;
713   }
714 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines