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 (10 days, 15 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

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.28 static const char RCSid[] = "$Id: renderopts.c,v 2.27 2025/04/22 17:12:25 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * renderopts.c - process common rendering options
6     *
7     * External symbols declared in ray.h
8     */
9    
10 greg 2.2 #include "copyright.h"
11 greg 2.1
12     #include "ray.h"
13 greg 2.27 #include "func.h"
14 greg 2.5 #include "paths.h"
15 greg 2.16 #include "pmapopt.h"
16 greg 2.1
17 greg 2.19 extern char *progname; /* global argv[0] */
18    
19     char RFeatureList[2048] = /* newline-separated feature list */
20 greg 2.20 "VirtualSources\nSecondarySources\nSourceSubsampling\n"
21     "SourceVisibility\nAmbientModifierSelection\n"
22     "PathTracing\nRussianRoulette\nLowDiscrepancySeq\n"
23     "SpecularSampling\nMaterialMixtures\nAntimatter\nBackFaceVisibility\n"
24 greg 2.22 "ScatteringModels=WGMD,Ashikhmin-Shirley\n"
25 greg 2.19 "TabulatedBSDFs=DataFile,KlemsXML,TensorTreeXML,+ViewPeakExtraction\n"
26     "Instancing=Octree,TriangleMesh\nAliases\n"
27 greg 2.23 #if MAXCSAMP>3
28     "Hyperspectral\n"
29     #endif
30 greg 2.19 #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 greg 2.26 if (!(n = cp - subfeat))
80     continue; /* empty subfeature */
81 greg 2.25 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 greg 2.19 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 greg 2.1
123 greg 2.15 int
124 schorsch 2.4 getrenderopt( /* get next render option */
125     int ac,
126     char *av[]
127     )
128 greg 2.1 {
129     #define check(ol,al) if (av[0][ol] || \
130     badarg(ac-1,av+1,al)) \
131     return(-1)
132 schorsch 2.17 #define check_bool(olen,var) switch (av[0][olen]) { \
133 greg 2.1 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 greg 2.10 case 'u': /* uncorrelated sampling */
147 schorsch 2.17 check_bool(2,rand_samp);
148 greg 2.9 return(0);
149 greg 2.1 case 'b': /* back face vis. */
150     if (av[0][2] == 'v') {
151 schorsch 2.17 check_bool(3,backvis);
152 greg 2.1 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 schorsch 2.17 check_bool(3,directvis);
179 greg 2.1 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 greg 2.14 case 's': /* sampling */
193 greg 2.1 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 schorsch 2.17 check_bool(2,do_irrad);
212 greg 2.1 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 greg 2.18 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
254 greg 2.3 getpath(av[1],getrlibpath(),R_OK));
255 greg 2.1 if (rval < 0) {
256     sprintf(errmsg,
257 greg 2.7 "cannot open ambient include file \"%s\"", av[1]);
258 greg 2.1 error(SYSTEM, errmsg);
259     }
260     amblp += rval;
261     } else {
262 greg 2.6 *amblp++ = savqstr(av[1]);
263 greg 2.1 *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 greg 2.18 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
275 greg 2.3 getpath(av[1],getrlibpath(),R_OK));
276 greg 2.1 if (rval < 0) {
277     sprintf(errmsg,
278 greg 2.7 "cannot open ambient exclude file \"%s\"", av[1]);
279 greg 2.1 error(SYSTEM, errmsg);
280     }
281     amblp += rval;
282     } else {
283 greg 2.6 *amblp++ = savqstr(av[1]);
284 greg 2.1 *amblp = NULL;
285     }
286     return(1);
287     case 'f': /* file */
288     check(3,"s");
289 greg 2.6 ambfile = savqstr(av[1]);
290 greg 2.1 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 greg 2.27 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 greg 2.23 #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 greg 2.24 return(2);
339 greg 2.23 }
340     break;
341     #endif
342 greg 2.1 }
343 greg 2.16
344     /* PMAP: Parse photon mapping options */
345     return(getPmapRenderOpt(ac, av));
346    
347     /* return(-1); */ /* unknown option */
348 greg 2.1
349     #undef check
350 schorsch 2.17 #undef check_bool
351 greg 2.1 }
352    
353    
354 greg 2.15 void
355 schorsch 2.4 print_rdefaults(void) /* print default render values to stdout */
356 greg 2.1 {
357     printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
358     "-i-\t\t\t\t# irradiance calculation off\n");
359 greg 2.11 printf(rand_samp ? "-u+\t\t\t\t# uncorrelated Monte Carlo sampling\n" :
360 greg 2.12 "-u-\t\t\t\t# correlated quasi-Monte Carlo sampling\n");
361 greg 2.1 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 greg 2.14 printf("-ss %f\t\t\t# specular sampling\n", specjitter);
372 greg 2.1 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 greg 2.23 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 greg 2.8 printf("-lr %-9d\t\t\t# limit reflection%s\n", maxdepth,
395     maxdepth<=0 ? " (Russian roulette)" : "");
396 greg 2.13 printf("-lw %.2e\t\t\t# limit weight\n", minweight);
397 greg 2.16
398     /* PMAP: output photon map defaults */
399     printPmapDefaults();
400 greg 2.1 }