--- ray/src/cv/mgflib/parser.c 1994/06/22 15:33:47 1.2 +++ ray/src/cv/mgflib/parser.c 1994/06/24 09:40:29 1.5 @@ -53,14 +53,19 @@ int mg_nqcdivs = MG_NQCD; /* number of divisions per q /* temporary settings for testing */ #define e_ies e_any_toss +#define e_cmix e_any_toss +#define e_cspec e_any_toss /* alternate handler routines */ static int e_any_toss(), /* discard unneeded entity */ e_ies(), /* IES luminaire file */ e_include(), /* include file */ e_sph(), /* sphere */ + e_cmix(), /* color mixtures */ + e_cspec(); /* color spectra */ e_cyl(), /* cylinder */ e_cone(), /* cone */ + e_prism(), /* prism */ e_ring(), /* ring */ e_torus(); /* torus */ @@ -103,11 +108,22 @@ mg_init() /* initialize alternate entity handlers */ ineed |= 1<n[0]==0. && cv->n[1]==0. && cv->n[2]==0.) + if (is0vect(cv->n)) return(MG_EILL); if (!isflt(av[2]) || !isflt(av[3])) return(MG_ETYPE); minrad = atof(av[2]); + round0(minrad); maxrad = atof(av[3]); /* check orientation */ if (minrad > 0.) @@ -629,11 +646,12 @@ char **av; return(MG_EARGC); if ((cv = c_getvert(av[1])) == NULL) return(MG_EUNDEF); - if (cv->n[0]==0. && cv->n[1]==0. && cv->n[2]==0.) + if (is0vect(cv->n)) return(MG_EILL); if (!isflt(av[2]) || !isflt(av[3])) return(MG_ETYPE); minrad = atof(av[2]); + round0(minrad); maxrad = atof(av[3]); if (minrad < 0. || maxrad <= minrad) return(MG_EILL); @@ -659,7 +677,7 @@ char **av; sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*u[j]*cos(theta) + maxrad*v[j]*sin(theta)); - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); @@ -685,11 +703,11 @@ char **av; sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*d); sprintf(p4[j], FLTFMT, cv->p[j] + minrad*d); } - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); @@ -734,7 +752,9 @@ char **av; if (!isflt(av[2]) || !isflt(av[4])) return(MG_ETYPE); rad1 = atof(av[2]); + round0(rad1); rad2 = atof(av[4]); + round0(rad2); if (rad1 == 0.) { if (rad2 == 0.) return(MG_EILL); @@ -758,13 +778,20 @@ char **av; if ((d = normalize(w)) == 0.) return(MG_EILL); n1off = n2off = (rad2 - rad1)/d; - if (warpconends) /* hack for e_sph and e_torus */ - n2off = tan(atan(n2off)-(PI/4)/mg_nqcdivs); - n2off = sgn*n2off; + if (warpconends) { /* hack for e_sph and e_torus */ + d = atan(n2off) - (PI/4)/mg_nqcdivs; + if (d <= -PI/2+FTINY) + n2off = -FHUGE; + else + n2off = tan(d); + } make_axes(u, v, w); for (j = 0; j < 3; j++) { sprintf(p3[j], FLTFMT, cv2->p[j] + rad2*u[j]); - sprintf(n3[j], FLTFMT, u[j] + w[j]*n2off); + if (n2off <= -FHUGE) + sprintf(n3[j], FLTFMT, -w[j]); + else + sprintf(n3[j], FLTFMT, u[j] + w[j]*n2off); } if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) return(rv); @@ -787,25 +814,34 @@ char **av; for (j = 0; j < 3; j++) { d = u[j]*cos(theta) + v[j]*sin(theta); sprintf(p3[j], FLTFMT, cv2->p[j] + rad2*d); - sprintf(n3[j], FLTFMT, d + w[j]*n2off); + if (n2off > -FHUGE) + sprintf(n3[j], FLTFMT, d + w[j]*n2off); } - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) + if (n2off > -FHUGE && + (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_FACE, 4, fent)) != MG_OK) return(rv); } } else { /* quads */ v1ent[3] = "_cv4"; - if (warpconends) /* hack for e_sph and e_torus */ - n1off = tan(atan(n1off)+(PI/4)/mg_nqcdivs); - n1off = sgn*n1off; + if (warpconends) { /* hack for e_sph and e_torus */ + d = atan(n1off) + (PI/4)/mg_nqcdivs; + if (d >= PI/2-FTINY) + n1off = FHUGE; + else + n1off = tan(atan(n1off)+(PI/4)/mg_nqcdivs); + } for (j = 0; j < 3; j++) { sprintf(p4[j], FLTFMT, cv1->p[j] + rad1*u[j]); - sprintf(n4[j], FLTFMT, u[j] + w[j]*n1off); + if (n1off >= FHUGE) + sprintf(n4[j], FLTFMT, w[j]); + else + sprintf(n4[j], FLTFMT, u[j] + w[j]*n1off); } if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK) return(rv); @@ -822,25 +858,110 @@ char **av; for (j = 0; j < 3; j++) { d = u[j]*cos(theta) + v[j]*sin(theta); sprintf(p3[j], FLTFMT, cv2->p[j] + rad2*d); - sprintf(n3[j], FLTFMT, d + w[j]*n2off); + if (n2off > -FHUGE) + sprintf(n3[j], FLTFMT, d + w[j]*n2off); sprintf(p4[j], FLTFMT, cv1->p[j] + rad1*d); - sprintf(n4[j], FLTFMT, d + w[j]*n1off); + if (n1off < FHUGE) + sprintf(n4[j], FLTFMT, d + w[j]*n1off); } - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) + if (n2off > -FHUGE && + (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK) + if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK) + if (n1off < FHUGE && + (rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK) return(rv); if ((rv = handle_it(MG_E_FACE, 5, fent)) != MG_OK) return(rv); } + } + return(MG_OK); +} + + +static int +e_prism(ac, av) /* turn a prism into polygons */ +int ac; +char **av; +{ + static char p[3][24]; + static char *vent[4] = {mg_ename[MG_E_VERTEX],NULL,"="}; + static char *pent[5] = {mg_ename[MG_E_POINT],p[0],p[1],p[2]}; + char *newav[MG_MAXARGC], nvn[MG_MAXARGC-1][8]; + double length; + FVECT v1, v2, v3, norm; + register C_VERTEX *cv; + C_VERTEX *cv0; + int rv; + register int i, j; + + if (ac < 5) + return(MG_EARGC); + if (!isflt(av[ac-1])) + return(MG_ETYPE); + length = atof(av[ac-1]); + if (length <= FTINY && length >= -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 = handle_it(MG_E_FACE, i, newav)) != MG_OK) + return(rv); + /* compute face normal */ + if ((cv0 = c_getvert(av[2])) == NULL) + return(MG_EUNDEF); + 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); + v2[0] = cv->p[0] - cv0->p[0]; + v2[1] = cv->p[1] - cv0->p[1]; + v2[2] = cv->p[2] - cv0->p[2]; + fcross(v3, v1, v2); + norm[0] += v3[0]; + norm[1] += v3[1]; + norm[2] += v3[2]; + VCOPY(v1, v2); + } + if (normalize(norm) == 0.) + return(MG_EILL); + /* create moved vertices */ + for (i = 1; i < ac-1; i++) { + sprintf(nvn[i-1], "_pv%d", i); + vent[1] = nvn[i-1]; + if ((rv = handle_it(MG_E_VERTEX, 3, 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 = handle_it(MG_E_POINT, 4, pent)) != MG_OK) + return(rv); + newav[ac-1-i] = nvn[i-1]; /* reverse */ + } + /* do top face */ + if ((rv = handle_it(MG_E_FACE, ac-1, newav)) != MG_OK) + return(rv); + /* do the side faces */ + newav[5] = NULL; + newav[3] = av[ac-2]; + newav[4] = nvn[ac-3]; + for (i = 1; i < ac-1; i++) { + newav[1] = nvn[i-1]; + newav[2] = av[i]; + if ((rv = handle_it(MG_E_FACE, 5, newav)) != MG_OK) + return(rv); + newav[3] = newav[2]; + newav[4] = newav[1]; } return(MG_OK); }