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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: renderopts.c,v 2.20 2022/10/19 23:10:34 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 "paths.h"
14 #include "pmapopt.h"
15
16 extern char *progname; /* global argv[0] */
17
18 char RFeatureList[2048] = /* newline-separated feature list */
19 "VirtualSources\nSecondarySources\nSourceSubsampling\n"
20 "SourceVisibility\nAmbientModifierSelection\n"
21 "PathTracing\nRussianRoulette\nLowDiscrepancySeq\n"
22 "SpecularSampling\nMaterialMixtures\nAntimatter\nBackFaceVisibility\n"
23 "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 (cp[-1] != ',') & (cp[-1] != '=') ||
78 (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
116 int
117 getrenderopt( /* get next render option */
118 int ac,
119 char *av[]
120 )
121 {
122 #define check(ol,al) if (av[0][ol] || \
123 badarg(ac-1,av+1,al)) \
124 return(-1)
125 #define check_bool(olen,var) switch (av[0][olen]) { \
126 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 case 'u': /* uncorrelated sampling */
140 check_bool(2,rand_samp);
141 return(0);
142 case 'b': /* back face vis. */
143 if (av[0][2] == 'v') {
144 check_bool(3,backvis);
145 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 check_bool(3,directvis);
172 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 case 's': /* sampling */
186 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 check_bool(2,do_irrad);
205 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 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
247 getpath(av[1],getrlibpath(),R_OK));
248 if (rval < 0) {
249 sprintf(errmsg,
250 "cannot open ambient include file \"%s\"", av[1]);
251 error(SYSTEM, errmsg);
252 }
253 amblp += rval;
254 } else {
255 *amblp++ = savqstr(av[1]);
256 *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 rval = wordfile(amblp, AMBLLEN-(amblp-amblist),
268 getpath(av[1],getrlibpath(),R_OK));
269 if (rval < 0) {
270 sprintf(errmsg,
271 "cannot open ambient exclude file \"%s\"", av[1]);
272 error(SYSTEM, errmsg);
273 }
274 amblp += rval;
275 } else {
276 *amblp++ = savqstr(av[1]);
277 *amblp = NULL;
278 }
279 return(1);
280 case 'f': /* file */
281 check(3,"s");
282 ambfile = savqstr(av[1]);
283 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
312 /* PMAP: Parse photon mapping options */
313 return(getPmapRenderOpt(ac, av));
314
315 /* return(-1); */ /* unknown option */
316
317 #undef check
318 #undef check_bool
319 }
320
321
322 void
323 print_rdefaults(void) /* print default render values to stdout */
324 {
325 printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" :
326 "-i-\t\t\t\t# irradiance calculation off\n");
327 printf(rand_samp ? "-u+\t\t\t\t# uncorrelated Monte Carlo sampling\n" :
328 "-u-\t\t\t\t# correlated quasi-Monte Carlo sampling\n");
329 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 printf("-ss %f\t\t\t# specular sampling\n", specjitter);
340 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 printf("-lr %-9d\t\t\t# limit reflection%s\n", maxdepth,
358 maxdepth<=0 ? " (Russian roulette)" : "");
359 printf("-lw %.2e\t\t\t# limit weight\n", minweight);
360
361 /* PMAP: output photon map defaults */
362 printPmapDefaults();
363 }