ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/renderopts.c
Revision: 2.28
Committed: Tue Apr 22 18:08:48 2025 UTC (9 days, 23 hours ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.27: +1 -5 lines
Log Message:
perf: Eliminated redundant tests

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: renderopts.c,v 2.27 2025/04/22 17:12:25 greg Exp $";
3 #endif
4 /*
5 * renderopts.c - process common rendering options
6 *
7 * External symbols declared in ray.h
8 */
9
10 #include "copyright.h"
11
12 #include "ray.h"
13 #include "func.h"
14 #include "paths.h"
15 #include "pmapopt.h"
16
17 extern char *progname; /* global argv[0] */
18
19 char RFeatureList[2048] = /* newline-separated feature list */
20 "VirtualSources\nSecondarySources\nSourceSubsampling\n"
21 "SourceVisibility\nAmbientModifierSelection\n"
22 "PathTracing\nRussianRoulette\nLowDiscrepancySeq\n"
23 "SpecularSampling\nMaterialMixtures\nAntimatter\nBackFaceVisibility\n"
24 "ScatteringModels=WGMD,Ashikhmin-Shirley\n"
25 "TabulatedBSDFs=DataFile,KlemsXML,TensorTreeXML,+ViewPeakExtraction\n"
26 "Instancing=Octree,TriangleMesh\nAliases\n"
27 #if MAXCSAMP>3
28 "Hyperspectral\n"
29 #endif
30 #if !defined(SHADCACHE) || SHADCACHE > 0
31 "ShadowCache\n"
32 #endif
33 #ifdef DISPERSE
34 "DielectricDispersion\n"
35 #endif
36 /* PMAP_FEATURES XXX @Roland: need to define this in pmapopt.h */
37 ;
38
39
40 static char *
41 get_feature( /* find a specific feature (with optional sublist) */
42 const char *feat
43 )
44 {
45 char *cp = RFeatureList;
46 int n = 0;
47
48 while ((feat[n] != '\0') & (feat[n] != '='))
49 n++;
50 if (!n)
51 return(NULL);
52 while (*cp) {
53 if (!strncmp(cp, feat, n) && (cp[n] == '\n') | !feat[n] | (cp[n] == feat[n]))
54 return(cp);
55 while (*cp++ != '\n')
56 ;
57 }
58 return(NULL);
59 }
60
61
62 static int
63 match_subfeatures( /* check if subfeatures are supported */
64 char *mysublist,
65 char *reqs
66 )
67 {
68 if (mysublist)
69 mysublist = strchr(mysublist, '=');
70 if (!mysublist++ | !reqs)
71 return(0); /* not a feature list */
72 while (*reqs) { /* check each of their subfeature requests */
73 char subfeat[64];
74 char *cp = subfeat;
75 int n;
76 while (*reqs && (*cp = *reqs++) != ',')
77 cp++;
78 *cp = '\0';
79 if (!(n = cp - subfeat))
80 continue; /* empty subfeature */
81 for (cp = mysublist; (cp = strstr(cp, subfeat)) != NULL; cp++)
82 if ((cp[-1] == ',') | (cp[-1] == '=') &&
83 (cp[n] == ',') | (cp[n] == '\n'))
84 break; /* match */
85 if (!cp)
86 return(0); /* missing this one! */
87 }
88 return(1); /* matched them all */
89 }
90
91
92 int
93 feature_status( /* report active feature list / check specifics */
94 int ac,
95 char *av[]
96 )
97 {
98 if (ac <= 0) /* report entire list? */
99 fputs(RFeatureList, stdout);
100
101 for ( ; ac-- > 0; av++) { /* check each argument */
102 char *cp;
103 if (!*av[0]) continue;
104 if ((cp = strchr(av[0], '=')) != NULL) {
105 if (!match_subfeatures(get_feature(av[0]), cp+1))
106 goto missing_feature;
107 } else if ((cp = get_feature(av[0])) != NULL) {
108 char *tp = strchr(cp, '=');
109 if (tp && tp < strchr(cp, '\n'))
110 do
111 fputc(*cp, stdout);
112 while (*cp++ != '\n');
113 } else
114 goto missing_feature;
115 }
116 return(0); /* return satisfactory status */
117 missing_feature: /* or report error */
118 fprintf(stderr, "%s: missing feature - %s\n", progname, av[0]);
119 return(1);
120 }
121
122
123 int
124 getrenderopt( /* get next render option */
125 int ac,
126 char *av[]
127 )
128 {
129 #define check(ol,al) if (av[0][ol] || \
130 badarg(ac-1,av+1,al)) \
131 return(-1)
132 #define check_bool(olen,var) switch (av[0][olen]) { \
133 case '\0': var = !var; break; \
134 case 'y': case 'Y': case 't': case 'T': \
135 case '+': case '1': var = 1; break; \
136 case 'n': case 'N': case 'f': case 'F': \
137 case '-': case '0': var = 0; break; \
138 default: return(-1); }
139 static char **amblp; /* pointer to build ambient list */
140 int rval;
141 /* is it even an option? */
142 if (ac < 1 || av[0] == NULL || av[0][0] != '-')
143 return(-1);
144 /* check if it's one we know */
145 switch (av[0][1]) {
146 case 'u': /* uncorrelated sampling */
147 check_bool(2,rand_samp);
148 return(0);
149 case 'b': /* back face vis. */
150 if (av[0][2] == 'v') {
151 check_bool(3,backvis);
152 return(0);
153 }
154 break;
155 case 'd': /* direct */
156 switch (av[0][2]) {
157 case 't': /* threshold */
158 check(3,"f");
159 shadthresh = atof(av[1]);
160 return(1);
161 case 'c': /* certainty */
162 check(3,"f");
163 shadcert = atof(av[1]);
164 return(1);
165 case 'j': /* jitter */
166 check(3,"f");
167 dstrsrc = atof(av[1]);
168 return(1);
169 case 'r': /* relays */
170 check(3,"i");
171 directrelay = atoi(av[1]);
172 return(1);
173 case 'p': /* pretest */
174 check(3,"i");
175 vspretest = atoi(av[1]);
176 return(1);
177 case 'v': /* visibility */
178 check_bool(3,directvis);
179 return(0);
180 case 's': /* size */
181 check(3,"f");
182 srcsizerat = atof(av[1]);
183 return(1);
184 }
185 break;
186 case 's': /* specular */
187 switch (av[0][2]) {
188 case 't': /* threshold */
189 check(3,"f");
190 specthresh = atof(av[1]);
191 return(1);
192 case 's': /* sampling */
193 check(3,"f");
194 specjitter = atof(av[1]);
195 return(1);
196 }
197 break;
198 case 'l': /* limit */
199 switch (av[0][2]) {
200 case 'r': /* recursion */
201 check(3,"i");
202 maxdepth = atoi(av[1]);
203 return(1);
204 case 'w': /* weight */
205 check(3,"f");
206 minweight = atof(av[1]);
207 return(1);
208 }
209 break;
210 case 'i': /* irradiance */
211 check_bool(2,do_irrad);
212 return(0);
213 case 'a': /* ambient */
214 switch (av[0][2]) {
215 case 'v': /* value */
216 check(3,"fff");
217 setcolor(ambval, atof(av[1]),
218 atof(av[2]),
219 atof(av[3]));
220 return(3);
221 case 'w': /* weight */
222 check(3,"i");
223 ambvwt = atoi(av[1]);
224 return(1);
225 case 'a': /* accuracy */
226 check(3,"f");
227 ambacc = atof(av[1]);
228 return(1);
229 case 'r': /* resolution */
230 check(3,"i");
231 ambres = atoi(av[1]);
232 return(1);
233 case 'd': /* divisions */
234 check(3,"i");
235 ambdiv = atoi(av[1]);
236 return(1);
237 case 's': /* super-samp */
238 check(3,"i");
239 ambssamp = atoi(av[1]);
240 return(1);
241 case 'b': /* bounces */
242 check(3,"i");
243 ambounce = atoi(av[1]);
244 return(1);
245 case 'i': /* include */
246 case 'I':
247 check(3,"s");
248 if (ambincl != 1) {
249 ambincl = 1;
250 amblp = amblist;
251 }
252 if (av[0][2] == 'I') { /* file */
253 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
254 getpath(av[1],getrlibpath(),R_OK));
255 if (rval < 0) {
256 sprintf(errmsg,
257 "cannot open ambient include file \"%s\"", av[1]);
258 error(SYSTEM, errmsg);
259 }
260 amblp += rval;
261 } else {
262 *amblp++ = savqstr(av[1]);
263 *amblp = NULL;
264 }
265 return(1);
266 case 'e': /* exclude */
267 case 'E':
268 check(3,"s");
269 if (ambincl != 0) {
270 ambincl = 0;
271 amblp = amblist;
272 }
273 if (av[0][2] == 'E') { /* file */
274 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
275 getpath(av[1],getrlibpath(),R_OK));
276 if (rval < 0) {
277 sprintf(errmsg,
278 "cannot open ambient exclude file \"%s\"", av[1]);
279 error(SYSTEM, errmsg);
280 }
281 amblp += rval;
282 } else {
283 *amblp++ = savqstr(av[1]);
284 *amblp = NULL;
285 }
286 return(1);
287 case 'f': /* file */
288 check(3,"s");
289 ambfile = savqstr(av[1]);
290 return(1);
291 }
292 break;
293 case 'm': /* medium */
294 switch (av[0][2]) {
295 case 'e': /* extinction */
296 check(3,"fff");
297 setcolor(cextinction, atof(av[1]),
298 atof(av[2]),
299 atof(av[3]));
300 return(3);
301 case 'a': /* albedo */
302 check(3,"fff");
303 setcolor(salbedo, atof(av[1]),
304 atof(av[2]),
305 atof(av[3]));
306 return(3);
307 case 'g': /* eccentr. */
308 check(3,"f");
309 seccg = atof(av[1]);
310 return(1);
311 case 's': /* sampling */
312 check(3,"f");
313 ssampdist = atof(av[1]);
314 return(1);
315 }
316 break;
317 case 'f': /* .cal file */
318 check(2,"s");
319 loadfunc(av[1]);
320 return(1);
321 case 'e': /* .cal expression */
322 check(2,"s");
323 if (!strchr(av[1], '=') && !strchr(av[1], ':'))
324 break;
325 scompile(av[1], NULL, 0);
326 return(1);
327 #if MAXCSAMP>3
328 case 'c': /* spectral sampling */
329 switch (av[0][2]) {
330 case 's': /* spectral bin count */
331 check(3,"i");
332 NCSAMP = atoi(av[1]);
333 return(1);
334 case 'w': /* wavelength extrema */
335 check(3,"ff");
336 WLPART[0] = atof(av[1]);
337 WLPART[3] = atof(av[2]);
338 return(2);
339 }
340 break;
341 #endif
342 }
343
344 /* PMAP: Parse photon mapping options */
345 return(getPmapRenderOpt(ac, av));
346
347 /* return(-1); */ /* unknown option */
348
349 #undef check
350 #undef check_bool
351 }
352
353
354 void
355 print_rdefaults(void) /* print default render values to stdout */
356 {
357 printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
358 "-i-\t\t\t\t# irradiance calculation off\n");
359 printf(rand_samp ? "-u+\t\t\t\t# uncorrelated Monte Carlo sampling\n" :
360 "-u-\t\t\t\t# correlated quasi-Monte Carlo sampling\n");
361 printf(backvis ? "-bv+\t\t\t\t# back face visibility on\n" :
362 "-bv-\t\t\t\t# back face visibility off\n");
363 printf("-dt %f\t\t\t# direct threshold\n", shadthresh);
364 printf("-dc %f\t\t\t# direct certainty\n", shadcert);
365 printf("-dj %f\t\t\t# direct jitter\n", dstrsrc);
366 printf("-ds %f\t\t\t# direct sampling\n", srcsizerat);
367 printf("-dr %-9d\t\t\t# direct relays\n", directrelay);
368 printf("-dp %-9d\t\t\t# direct pretest density\n", vspretest);
369 printf(directvis ? "-dv+\t\t\t\t# direct visibility on\n" :
370 "-dv-\t\t\t\t# direct visibility off\n");
371 printf("-ss %f\t\t\t# specular sampling\n", specjitter);
372 printf("-st %f\t\t\t# specular threshold\n", specthresh);
373 printf("-av %f %f %f\t# ambient value\n", colval(ambval,RED),
374 colval(ambval,GRN), colval(ambval, BLU));
375 printf("-aw %-9d\t\t\t# ambient value weight\n", ambvwt);
376 printf("-ab %-9d\t\t\t# ambient bounces\n", ambounce);
377 printf("-aa %f\t\t\t# ambient accuracy\n", ambacc);
378 printf("-ar %-9d\t\t\t# ambient resolution\n", ambres);
379 printf("-ad %-9d\t\t\t# ambient divisions\n", ambdiv);
380 printf("-as %-9d\t\t\t# ambient super-samples\n", ambssamp);
381 printf("-me %.2e %.2e %.2e\t# mist extinction coefficient\n",
382 colval(cextinction,RED),
383 colval(cextinction,GRN),
384 colval(cextinction,BLU));
385 printf("-ma %f %f %f\t# mist scattering albedo\n", colval(salbedo,RED),
386 colval(salbedo,GRN), colval(salbedo,BLU));
387 printf("-mg %f\t\t\t# mist scattering eccentricity\n", seccg);
388 printf("-ms %f\t\t\t# mist sampling distance\n", ssampdist);
389 if (NCSAMP > 3) {
390 printf("-cs %-2d\t\t\t\t# number of spectral bins\n", NCSAMP);
391 printf("-cw %3.0f %3.0f\t\t\t# wavelength limits (nm)\n",
392 WLPART[3], WLPART[0]);
393 }
394 printf("-lr %-9d\t\t\t# limit reflection%s\n", maxdepth,
395 maxdepth<=0 ? " (Russian roulette)" : "");
396 printf("-lw %.2e\t\t\t# limit weight\n", minweight);
397
398 /* PMAP: output photon map defaults */
399 printPmapDefaults();
400 }