--- ray/src/rt/renderopts.c 2015/02/24 19:39:27 2.16 +++ ray/src/rt/renderopts.c 2022/10/19 21:25:20 2.19 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: renderopts.c,v 2.16 2015/02/24 19:39:27 greg Exp $"; +static const char RCSid[] = "$Id: renderopts.c,v 2.19 2022/10/19 21:25:20 greg Exp $"; #endif /* * renderopts.c - process common rendering options @@ -13,8 +13,106 @@ static const char RCSid[] = "$Id: renderopts.c,v 2.16 #include "paths.h" #include "pmapopt.h" +extern char *progname; /* global argv[0] */ +char RFeatureList[2048] = /* newline-separated feature list */ + "AdaptiveShadowTesting\nVirtualSources\nSecondarySources\n" + "SourceSubsampling\nSourceVisibility\nAmbientModifierSelection\n" + "PathTracing\nBackFaceVisibility\nRussianRoulette\nLowDiscrepancySeq\n" + "SpecularSampling\nMaterialMixtures\nAntimatter\n" + "ParticipatingMedia=Mist\nScatteringModels=WGMD,Ashikhmin-Shirley\n" + "TabulatedBSDFs=DataFile,KlemsXML,TensorTreeXML,+ViewPeakExtraction\n" + "Instancing=Octree,TriangleMesh\nAliases\n" +#if !defined(SHADCACHE) || SHADCACHE > 0 + "ShadowCache\n" +#endif +#ifdef DISPERSE + "DielectricDispersion\n" +#endif +/* PMAP_FEATURES XXX @Roland: need to define this in pmapopt.h */ +; + + +static char * +get_feature( /* find a specific feature (with optional sublist) */ + const char *feat +) +{ + char *cp = RFeatureList; + int n = 0; + + while ((feat[n] != '\0') & (feat[n] != '=')) + n++; + if (!n) + return(NULL); + while (*cp) { + if (!strncmp(cp, feat, n) && (cp[n] == '\n') | !feat[n] | (cp[n] == feat[n])) + return(cp); + while (*cp++ != '\n') + ; + } + return(NULL); +} + + +static int +match_subfeatures( /* check if subfeatures are supported */ + char *mysublist, + char *reqs +) +{ + if (mysublist) + mysublist = strchr(mysublist, '='); + if (!mysublist++ | !reqs) + return(0); /* not a feature list */ + while (*reqs) { /* check each of their subfeature requests */ + char subfeat[64]; + char *cp = subfeat; + int n; + while (*reqs && (*cp = *reqs++) != ',') + cp++; + *cp = '\0'; + n = cp - subfeat; + if (!(cp = strstr(mysublist, subfeat)) || + (cp[n] != ',') & (cp[n] != '\n')) + return(0); /* missing this one! */ + } + return(1); /* matched them all */ +} + + int +feature_status( /* report active feature list / check specifics */ + int ac, + char *av[] +) +{ + if (ac <= 0) /* report entire list? */ + fputs(RFeatureList, stdout); + + for ( ; ac-- > 0; av++) { /* check each argument */ + char *cp; + if (!*av[0]) continue; + if ((cp = strchr(av[0], '=')) != NULL) { + if (!match_subfeatures(get_feature(av[0]), cp+1)) + goto missing_feature; + } else if ((cp = get_feature(av[0])) != NULL) { + char *tp = strchr(cp, '='); + if (tp && tp < strchr(cp, '\n')) + do + fputc(*cp, stdout); + while (*cp++ != '\n'); + } else + goto missing_feature; + } + return(0); /* return satisfactory status */ +missing_feature: /* or report error */ + fprintf(stderr, "%s: missing feature - %s\n", progname, av[0]); + return(1); +} + + +int getrenderopt( /* get next render option */ int ac, char *av[] @@ -23,7 +121,7 @@ getrenderopt( /* get next render option */ #define check(ol,al) if (av[0][ol] || \ badarg(ac-1,av+1,al)) \ return(-1) -#define bool(olen,var) switch (av[0][olen]) { \ +#define check_bool(olen,var) switch (av[0][olen]) { \ case '\0': var = !var; break; \ case 'y': case 'Y': case 't': case 'T': \ case '+': case '1': var = 1; break; \ @@ -38,11 +136,11 @@ getrenderopt( /* get next render option */ /* check if it's one we know */ switch (av[0][1]) { case 'u': /* uncorrelated sampling */ - bool(2,rand_samp); + check_bool(2,rand_samp); return(0); case 'b': /* back face vis. */ if (av[0][2] == 'v') { - bool(3,backvis); + check_bool(3,backvis); return(0); } break; @@ -69,7 +167,7 @@ getrenderopt( /* get next render option */ vspretest = atoi(av[1]); return(1); case 'v': /* visibility */ - bool(3,directvis); + check_bool(3,directvis); return(0); case 's': /* size */ check(3,"f"); @@ -102,7 +200,7 @@ getrenderopt( /* get next render option */ } break; case 'i': /* irradiance */ - bool(2,do_irrad); + check_bool(2,do_irrad); return(0); case 'a': /* ambient */ switch (av[0][2]) { @@ -144,7 +242,7 @@ getrenderopt( /* get next render option */ amblp = amblist; } if (av[0][2] == 'I') { /* file */ - rval = wordfile(amblp, + rval = wordfile(amblp, AMBLLEN-(amblp-amblist), getpath(av[1],getrlibpath(),R_OK)); if (rval < 0) { sprintf(errmsg, @@ -165,7 +263,7 @@ getrenderopt( /* get next render option */ amblp = amblist; } if (av[0][2] == 'E') { /* file */ - rval = wordfile(amblp, + rval = wordfile(amblp, AMBLLEN-(amblp-amblist), getpath(av[1],getrlibpath(),R_OK)); if (rval < 0) { sprintf(errmsg, @@ -216,7 +314,7 @@ getrenderopt( /* get next render option */ /* return(-1); */ /* unknown option */ #undef check -#undef bool +#undef check_bool }