--- ray/src/rt/p_data.c 2023/11/15 18:02:53 2.10 +++ ray/src/rt/p_data.c 2024/03/12 16:54:51 2.15 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id: p_data.c,v 2.10 2023/11/15 18:02:53 greg Exp $"; +static const char RCSid[] = "$Id: p_data.c,v 2.15 2024/03/12 16:54:51 greg Exp $"; #endif /* * p_data.c - routine for stored patterns. @@ -49,14 +49,30 @@ static const char RCSid[] = "$Id: p_data.c,v 2.10 2023 * 0 * 0 * + * A spectral data file is given as: + * + * modifier specdata name + * 4+ sfunc dfname vfname v0 .. xf + * 0 + * n A1 A2 .. + * + * A spectral image is given as: + * + * modifier specpict name + * 5+ sfunc sfname vfname vx vy xf + * 0 + * n A1 A2 .. + * * Vfname is the name of the file where the variable definitions * can be found. The list of real arguments can be accessed by * definitions in the file. The dfnames are the data file * names. The dimensions of the data files and the number - * of variables must match. The funcs take a single argument - * for brightdata, and three for colordata and colorpict to produce - * interpolated values from the file. The xf is a transform spec - * to get from the original coordinates to the current coordinates. + * of variables must match, except for specdata, which has a "hidden" + * last variable for the wavelength. The funcs take a single argument + * for brightdata, three for colordata and colorpict, and two for + * specdata and specpict to modify interpolated values from the file. + * The xf is a transform spec to get from the original coordinates to + * the current coordinates. */ @@ -125,14 +141,18 @@ p_cdata( /* interpolate color data */ } col[0] = datavalue(dp, pt); for (i = 1; i < 3; i++) { - dp = getdata(m->oargs.sarg[i+3]); + if (!strcmp(m->oargs.sarg[3+i], m->oargs.sarg[3])) { + col[i] = col[0]; /* same data */ + continue; + } + dp = getdata(m->oargs.sarg[3+i]); if (dp->nd != nv) objerror(m, USER, "dimension error"); col[i] = datavalue(dp, pt); } errno = 0; for (i = 0; i < 3; i++) - if (fundefined(m->oargs.sarg[i]) < 3) + if (i && fundefined(m->oargs.sarg[i]) < 3) colval(cval,i) = funvalue(m->oargs.sarg[i], 1, col+i); else colval(cval,i) = funvalue(m->oargs.sarg[i], 3, col); @@ -173,7 +193,7 @@ p_pdata( /* interpolate picture data */ col[i] = datavalue(dp+i, pt); errno = 0; for (i = 0; i < 3; i++) - if (fundefined(m->oargs.sarg[i]) < 3) + if (i && fundefined(m->oargs.sarg[i]) < 3) colval(cval,i) = funvalue(m->oargs.sarg[i], 1, col+i); else colval(cval,i) = funvalue(m->oargs.sarg[i], 3, col); @@ -210,8 +230,7 @@ p_spectrum( /* simple constant spectrum */ sinp[i] = (COLORV)m->oargs.farg[i+2]; hstep = 0.5 * (m->oargs.farg[1] - m->oargs.farg[0]) / (m->oargs.nfargs-3.0); - convertscolor(scval, NCSAMP, WLPART[0], WLPART[3], - sinp, m->oargs.nfargs-2, + convertscolorcol(scval, sinp, m->oargs.nfargs-2, m->oargs.farg[0]-hstep, m->oargs.farg[1]+hstep); free(sinp); m->os = (void *)scval; @@ -249,12 +268,111 @@ p_specfile( /* constant spectrum from 1-D data file double wl = dp->dim[0].org + i*step; sinp[i] = (COLORV)datavalue(dp, &wl); } - convertscolor(scval, NCSAMP, WLPART[0], WLPART[3], - sinp, dp->dim[0].ne, dp->dim[0].org-.5*step, + convertscolorcol(scval, sinp, dp->dim[0].ne, + dp->dim[0].org-.5*step, dp->dim[0].org+dp->dim[0].siz+.5*step); free(sinp); m->os = (void *)scval; } smultscolor(r->pcol, scval); + return(0); +} + + +int +p_specdata( /* varied spectrum from (N+1)-D file */ + OBJREC *m, + RAY *r +) +{ + SCOLOR scval; + COLORV *scdat; + double pt[MAXDDIM]; + DATARRAY *dp; + MFUNC *mf; + double step; + int i; + + if (m->oargs.nsargs < 4) + objerror(m, USER, "bad # arguments"); + dp = getdata(m->oargs.sarg[1]); + if (dp->nd < 2) + objerror(m, USER, "need at least 2-dimensional data"); + i = (1 << (dp->nd-1)) - 1; + mf = getfunc(m, 2, i<<3, 0); + setfunc(m, r); + errno = 0; + for (i = dp->nd-1; i-- > 0; ) { + pt[i] = evalue(mf->ep[i]); + if ((errno == EDOM) | (errno == ERANGE)) + goto computerr; + } + dp = datavector(dp, pt); /* interpolate spectrum */ + step = dp->dim[0].siz / (dp->dim[0].ne - 1.0); + scdat = (COLORV *)malloc(sizeof(COLORV)*dp->dim[0].ne); + if (scdat == NULL) + objerror(m, SYSTEM, "out of memory"); + for (i = dp->dim[0].ne; i-- > 0; ) { + pt[1] = dp->dim[0].org + i*step; + pt[0] = datavalue(dp, pt+1); + errno = 0; + scdat[i] = funvalue(m->oargs.sarg[0], 2, pt); + if ((errno == EDOM) | (errno == ERANGE)) + goto computerr; + } + convertscolorcol(scval, scdat, dp->dim[0].ne, + dp->dim[0].org-.5*step, + dp->dim[0].org+dp->dim[0].siz+.5*step); + free(scdat); + free(dp); + smultscolor(r->pcol, scval); + return(0); +computerr: + objerror(m, WARNING, "compute error"); + return(0); +} + + +int +p_specpict( /* interpolate hyperspectral image data */ + OBJREC *m, + RAY *r +) +{ + SCOLOR scdat, scval; + double pt[2]; + DATARRAY *dp; + MFUNC *mf; + double step; + int i; + + if (m->oargs.nsargs < 5) + objerror(m, USER, "bad # arguments"); + mf = getfunc(m, 2, 0x3<<3, 0); + setfunc(m, r); + errno = 0; + pt[1] = evalue(mf->ep[0]); /* y major ordering */ + pt[0] = evalue(mf->ep[1]); + if ((errno == EDOM) | (errno == ERANGE)) + goto computerr; + /* interpolate spectrum */ + dp = datavector(getspec(m->oargs.sarg[1]), pt); + step = dp->dim[0].siz / (dp->dim[0].ne - 1.0); + for (i = dp->dim[0].ne; i-- > 0; ) { + pt[1] = dp->dim[0].org + i*step; + pt[0] = dp->arr.d[i]; /* datavalue(dp, pt+1); */ + errno = 0; + scdat[i] = funvalue(m->oargs.sarg[0], 2, pt); + if ((errno == EDOM) | (errno == ERANGE)) + goto computerr; + } + convertscolorcol(scval, scdat, dp->dim[0].ne, + dp->dim[0].org-.5*step, + dp->dim[0].org+dp->dim[0].siz+.5*step); + free(dp); + smultscolor(r->pcol, scval); + return(0); +computerr: + objerror(m, WARNING, "compute error"); return(0); }