--- ray/src/cv/mgflib/parser.c 1994/06/29 16:15:20 1.10 +++ ray/src/cv/mgflib/parser.c 1995/03/07 14:53:23 1.13 @@ -59,6 +59,7 @@ static int e_any_toss(), /* discard unneeded entity * e_ies(), /* IES luminaire file */ e_include(), /* include file */ e_sph(), /* sphere */ + e_cct(), /* color temperature */ e_cmix(), /* color mixtures */ e_cspec(), /* color spectra */ e_cyl(), /* cylinder */ @@ -119,12 +120,16 @@ mg_init() /* initialize alternate entity handlers */ if (mg_ehand[MG_E_COLOR] != NULL) { if (mg_ehand[MG_E_CMIX] == NULL) { mg_ehand[MG_E_CMIX] = e_cmix; - ineed |= 1<= -FTINY) return(MG_EILL); - /* do bottom face */ - newav[0] = mg_ename[MG_E_FACE]; - for (i = 1; i < ac-1; i++) - newav[i] = av[i]; - newav[i] = NULL; - if ((rv = mg_handle(MG_E_FACE, i, newav)) != MG_OK) - return(rv); - /* compute face normal */ + /* compute face normal */ if ((cv0 = c_getvert(av[1])) == NULL) return(MG_EUNDEF); + hasnorm = 0; norm[0] = norm[1] = norm[2] = 0.; v1[0] = v1[1] = v1[2] = 0.; for (i = 2; i < ac-1; i++) { if ((cv = c_getvert(av[i])) == NULL) return(MG_EUNDEF); + hasnorm += !is0vect(cv->n); v2[0] = cv->p[0] - cv0->p[0]; v2[1] = cv->p[1] - cv0->p[1]; v2[2] = cv->p[2] - cv0->p[2]; @@ -908,22 +912,21 @@ char **av; } if (normalize(norm) == 0.) return(MG_EILL); - /* create moved vertices */ + /* create moved vertices */ for (i = 1; i < ac-1; i++) { sprintf(nvn[i-1], "_pv%d", i); vent[1] = nvn[i-1]; - if ((rv = mg_handle(MG_E_VERTEX, 3, vent)) != MG_OK) + vent[3] = av[i]; + if ((rv = mg_handle(MG_E_VERTEX, 4, vent)) != MG_OK) return(rv); cv = c_getvert(av[i]); /* checked above */ for (j = 0; j < 3; j++) sprintf(p[j], FLTFMT, cv->p[j] - length*norm[j]); if ((rv = mg_handle(MG_E_POINT, 4, pent)) != MG_OK) return(rv); - newav[ac-1-i] = nvn[i-1]; /* reverse */ } - /* do top face */ - if ((rv = mg_handle(MG_E_FACE, ac-1, newav)) != MG_OK) - return(rv); + /* make faces */ + newav[0] = mg_ename[MG_E_FACE]; /* do the side faces */ newav[5] = NULL; newav[3] = av[ac-2]; @@ -936,27 +939,92 @@ char **av; newav[3] = newav[2]; newav[4] = newav[1]; } + /* do top face */ + for (i = 1; i < ac-1; i++) { + if (hasnorm) { /* zero normals */ + vent[1] = nvn[i-1]; + if ((rv = mg_handle(MG_E_VERTEX, 2, vent)) != MG_OK) + return(rv); + if ((rv = mg_handle(MG_E_NORMAL, 4, znorm)) != MG_OK) + return(rv); + } + newav[ac-1-i] = nvn[i-1]; /* reverse */ + } + if ((rv = mg_handle(MG_E_FACE, ac-1, newav)) != MG_OK) + return(rv); + /* do bottom face */ + if (hasnorm) + for (i = 1; i < ac-1; i++) { + vent[1] = nvn[i-1]; + vent[3] = av[i]; + if ((rv = mg_handle(MG_E_VERTEX, 4, vent)) != MG_OK) + return(rv); + if ((rv = mg_handle(MG_E_NORMAL, 4, znorm)) != MG_OK) + return(rv); + newav[i] = nvn[i-1]; + } + else + for (i = 1; i < ac-1; i++) + newav[i] = av[i]; + newav[i] = NULL; + if ((rv = mg_handle(MG_E_FACE, i, newav)) != MG_OK) + return(rv); return(MG_OK); } static int -e_cspec(ac, av) /* handle spectral color */ -int ac; -char **av; +put_cxy() /* put out current xy chromaticities */ { static char xbuf[24], ybuf[24]; static char *ccom[4] = {mg_ename[MG_E_CXY], xbuf, ybuf}; int rv; + sprintf(xbuf, "%.4f", c_ccolor->cx); + sprintf(ybuf, "%.4f", c_ccolor->cy); + if ((rv = mg_handle(MG_E_CXY, 3, ccom)) != MG_OK) + return(rv); + return(MG_OK); +} + + +static int +put_cspec() /* put out current color spectrum */ +{ + char wl[2][6], vbuf[C_CNSS][24]; + char *newav[C_CNSS+4]; + double sf; + register int i; + + if (mg_ehand[MG_E_CSPEC] != c_hcolor) { + sprintf(wl[0], "%d", C_CMINWL); + sprintf(wl[1], "%d", C_CMAXWL); + newav[0] = mg_ename[MG_E_CSPEC]; + newav[1] = wl[0]; + newav[2] = wl[1]; + sf = (double)C_CNSS / c_ccolor->ssum; + for (i = 0; i < C_CNSS; i++) { + sprintf(vbuf[i], "%.6f", sf*c_ccolor->ssamp[i]); + newav[i+3] = vbuf[i]; + } + newav[C_CNSS+3] = NULL; + if ((i = mg_handle(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK) + return(i); + } + return(MG_OK); +} + + +static int +e_cspec(ac, av) /* handle spectral color */ +int ac; +char **av; +{ + /* convert to xy chromaticity */ c_ccvt(c_ccolor, C_CSXY); /* if it's really their handler, use it */ - if (mg_ehand[MG_E_CXY] != c_hcolor) { - sprintf(xbuf, "%.4f", c_ccolor->cx); - sprintf(ybuf, "%.4f", c_ccolor->cy); - if ((rv = mg_handle(MG_E_CXY, 3, ccom)) != MG_OK) - return(rv); - } + if (mg_ehand[MG_E_CXY] != c_hcolor) + return(put_cxy()); return(MG_OK); } @@ -966,10 +1034,6 @@ e_cmix(ac, av) /* handle mixing of colors */ int ac; char **av; { - char wl[2][6], vbuf[C_CNSS][24]; - char *newav[C_CNSS+4]; - int rv; - register int i; /* * Contorted logic works as follows: * 1. the colors are already mixed in c_hcolor() support function @@ -980,34 +1044,29 @@ char **av; */ if (mg_ehand[MG_E_CSPEC] == e_cspec) c_ccvt(c_ccolor, C_CSXY); - else if (c_ccolor->flags & C_CDSPEC) { - if (mg_ehand[MG_E_CSPEC] != c_hcolor) { - sprintf(wl[0], "%d", C_CMINWL); - sprintf(wl[1], "%d", C_CMAXWL); - newav[0] = mg_ename[MG_E_CSPEC]; - newav[1] = wl[0]; - newav[2] = wl[1]; - for (i = 0; i < C_CNSS; i++) { - sprintf(vbuf[i], "%.6f", - (double)c_ccolor->ssamp[i] / - c_ccolor->ssum); - newav[i+3] = vbuf[i]; - } - newav[C_CNSS+3] = NULL; - if ((rv = mg_handle(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK) - return(rv); - } - return(MG_OK); - } - if (mg_ehand[MG_E_CXY] != c_hcolor) { - sprintf(vbuf[0], "%.4f", c_ccolor->cx); - sprintf(vbuf[1], "%.4f", c_ccolor->cy); - newav[0] = mg_ename[MG_E_CXY]; - newav[1] = vbuf[0]; - newav[2] = vbuf[1]; - newav[3] = NULL; - if ((rv = mg_handle(MG_E_CXY, 3, newav)) != MG_OK) - return(rv); - } + else if (c_ccolor->flags & C_CDSPEC) + return(put_cspec()); + if (mg_ehand[MG_E_CXY] != c_hcolor) + return(put_cxy()); + return(MG_OK); +} + + +static int +e_cct(ac, av) /* handle color temperature */ +int ac; +char **av; +{ + /* + * Logic is similar to e_cmix here. Support handler has already + * converted temperature to spectral color. Put it out as such + * if they support it, otherwise convert to xy chromaticity and + * put it out if they handle it. + */ + if (mg_ehand[MG_E_CSPEC] != e_cspec) + return(put_cspec()); + c_ccvt(c_ccolor, C_CSXY); + if (mg_ehand[MG_E_CXY] != c_hcolor) + return(put_cxy()); return(MG_OK); }