--- ray/src/rt/renderopts.c 2004/08/20 20:03:00 2.7 +++ ray/src/rt/renderopts.c 2023/11/17 20:02:07 2.23 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: renderopts.c,v 2.7 2004/08/20 20:03:00 greg Exp $"; +static const char RCSid[] = "$Id: renderopts.c,v 2.23 2023/11/17 20:02:07 greg Exp $"; #endif /* * renderopts.c - process common rendering options @@ -11,9 +11,112 @@ static const char RCSid[] = "$Id: renderopts.c,v 2.7 2 #include "ray.h" #include "paths.h" +#include "pmapopt.h" +extern char *progname; /* global argv[0] */ -extern int +char RFeatureList[2048] = /* newline-separated feature list */ + "VirtualSources\nSecondarySources\nSourceSubsampling\n" + "SourceVisibility\nAmbientModifierSelection\n" + "PathTracing\nRussianRoulette\nLowDiscrepancySeq\n" + "SpecularSampling\nMaterialMixtures\nAntimatter\nBackFaceVisibility\n" + "ScatteringModels=WGMD,Ashikhmin-Shirley\n" + "TabulatedBSDFs=DataFile,KlemsXML,TensorTreeXML,+ViewPeakExtraction\n" + "Instancing=Octree,TriangleMesh\nAliases\n" +#if MAXCSAMP>3 + "Hyperspectral\n" +#endif +#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[-1] != ',') & (cp[-1] != '=') || + (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[] @@ -22,7 +125,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; \ @@ -36,9 +139,12 @@ getrenderopt( /* get next render option */ return(-1); /* check if it's one we know */ switch (av[0][1]) { + case 'u': /* uncorrelated sampling */ + 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; @@ -65,7 +171,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"); @@ -79,7 +185,7 @@ getrenderopt( /* get next render option */ check(3,"f"); specthresh = atof(av[1]); return(1); - case 'j': /* jitter */ + case 's': /* sampling */ check(3,"f"); specjitter = atof(av[1]); return(1); @@ -98,7 +204,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]) { @@ -140,7 +246,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, @@ -161,7 +267,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, @@ -204,19 +310,40 @@ getrenderopt( /* get next render option */ return(1); } break; +#if MAXCSAMP>3 + case 'c': /* spectral sampling */ + switch (av[0][2]) { + case 's': /* spectral bin count */ + check(3,"i"); + NCSAMP = atoi(av[1]); + return(1); + case 'w': /* wavelength extrema */ + check(3,"ff"); + WLPART[0] = atof(av[1]); + WLPART[3] = atof(av[2]); + return(1); + } + break; +#endif } - return(-1); /* unknown option */ + + /* PMAP: Parse photon mapping options */ + return(getPmapRenderOpt(ac, av)); + +/* return(-1); */ /* unknown option */ #undef check -#undef bool +#undef check_bool } -extern void +void print_rdefaults(void) /* print default render values to stdout */ { printf(do_irrad ? "-i+\t\t\t\t# irradiance calculation on\n" : "-i-\t\t\t\t# irradiance calculation off\n"); + printf(rand_samp ? "-u+\t\t\t\t# uncorrelated Monte Carlo sampling\n" : + "-u-\t\t\t\t# correlated quasi-Monte Carlo sampling\n"); printf(backvis ? "-bv+\t\t\t\t# back face visibility on\n" : "-bv-\t\t\t\t# back face visibility off\n"); printf("-dt %f\t\t\t# direct threshold\n", shadthresh); @@ -227,7 +354,7 @@ print_rdefaults(void) /* print default render values printf("-dp %-9d\t\t\t# direct pretest density\n", vspretest); printf(directvis ? "-dv+\t\t\t\t# direct visibility on\n" : "-dv-\t\t\t\t# direct visibility off\n"); - printf("-sj %f\t\t\t# specular jitter\n", specjitter); + printf("-ss %f\t\t\t# specular sampling\n", specjitter); printf("-st %f\t\t\t# specular threshold\n", specthresh); printf("-av %f %f %f\t# ambient value\n", colval(ambval,RED), colval(ambval,GRN), colval(ambval, BLU)); @@ -245,6 +372,15 @@ print_rdefaults(void) /* print default render values colval(salbedo,GRN), colval(salbedo,BLU)); printf("-mg %f\t\t\t# mist scattering eccentricity\n", seccg); printf("-ms %f\t\t\t# mist sampling distance\n", ssampdist); - printf("-lr %-9d\t\t\t# limit reflection\n", maxdepth); - printf("-lw %f\t\t\t# limit weight\n", minweight); + if (NCSAMP > 3) { + printf("-cs %-2d\t\t\t\t# number of spectral bins\n", NCSAMP); + printf("-cw %3.0f %3.0f\t\t\t# wavelength limits (nm)\n", + WLPART[3], WLPART[0]); + } + printf("-lr %-9d\t\t\t# limit reflection%s\n", maxdepth, + maxdepth<=0 ? " (Russian roulette)" : ""); + printf("-lw %.2e\t\t\t# limit weight\n", minweight); + + /* PMAP: output photon map defaults */ + printPmapDefaults(); }