ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/renderopts.c
Revision: 2.21
Committed: Mon Aug 14 23:45:41 2023 UTC (9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.20: +2 -1 lines
Log Message:
fix: tighter requirements on subfeature list

File Contents

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