--- ray/src/cv/mgflib/parser.c 1994/06/25 09:48:03 1.8 +++ ray/src/cv/mgflib/parser.c 1995/10/27 15:47:18 1.19 @@ -1,4 +1,4 @@ -/* Copyright (c) 1994 Regents of the University of California */ +/* Copyright (c) 1995 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -27,6 +27,12 @@ char mg_ename[MG_NENTITIES][MG_MAXELEN] = MG_NAMELIST; int (*mg_ehand[MG_NENTITIES])(); + /* Handler routine for unknown entities */ + +int (*mg_uhand)() = mg_defuhand; + +unsigned mg_nunknown; /* count of unknown entities */ + /* error messages */ char *mg_err[MG_NERRS] = MG_ERRLIST; @@ -59,6 +65,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 */ @@ -88,76 +95,84 @@ mg_init() /* initialize alternate entity handlers */ mg_ehand[MG_E_INCLUDE] = e_include; if (mg_ehand[MG_E_SPH] == NULL) { mg_ehand[MG_E_SPH] = e_sph; - ineed |= 1<fid = ++nfids; ctx->lineno = 0; if (fn == NULL) { strcpy(ctx->fname, ""); @@ -222,14 +240,11 @@ char *fn; return(MG_OK); } /* get name relative to this context */ - if (mg_file != NULL && - (cp = strrchr(mg_file->fname, '/')) != NULL) - olen = cp - mg_file->fname + 1; - else - olen = 0; - if (olen) + if (mg_file != NULL && (cp = strrchr(mg_file->fname, '/')) != NULL) { strcpy(ctx->fname, mg_file->fname); - strcpy(ctx->fname+olen, fn); + strcpy(ctx->fname+(cp-mg_file->fname+1), fn); + } else + strcpy(ctx->fname, fn); ctx->fp = fopen(ctx->fname, "r"); if (ctx->fp == NULL) return(MG_ENOFILE); @@ -251,16 +266,31 @@ mg_close() /* close input file */ } +void +mg_fgetpos(pos) /* get current position in input file */ +register MG_FPOS *pos; +{ + extern long ftell(); + + pos->fid = mg_file->fid; + pos->lineno = mg_file->lineno; + pos->offset = ftell(mg_file->fp); +} + + int -mg_rewind() /* rewind input file */ +mg_fgoto(pos) /* reposition input file pointer */ +register MG_FPOS *pos; { - if (mg_file->lineno == 0) + if (pos->fid != mg_file->fid) + return(MG_ESEEK); + if (pos->lineno == mg_file->lineno) return(MG_OK); if (mg_file->fp == stdin) return(MG_ESEEK); /* cannot seek on standard input */ - if (fseek(mg_file->fp, 0L, 0) == EOF) + if (fseek(mg_file->fp, pos->offset, 0) == EOF) return(MG_ESEEK); - mg_file->lineno = 0; + mg_file->lineno = pos->lineno; return(MG_OK); } @@ -309,7 +339,7 @@ mg_parse() /* parse current input line */ return(MG_OK); /* no words in line */ *ap = NULL; /* else handle it */ - return(handle_it(-1, ap-argv, argv)); + return(mg_handle(-1, ap-argv, argv)); } @@ -336,6 +366,18 @@ char *fn; } +int +mg_defuhand(ac, av) /* default handler for unknown entities */ +int ac; +char **av; +{ + if (mg_nunknown++ == 0) /* report first incident */ + fprintf(stderr, "%s: %d: %s: %s\n", mg_file->fname, + mg_file->lineno, mg_err[MG_EUNK], av[0]); + return(MG_OK); +} + + void mg_clear() /* clear parser history */ { @@ -344,59 +386,6 @@ mg_clear() /* clear parser history */ } -int -mg_iterate(ac, av, f) /* iterate on statement */ -int ac; -register char **av; -int (*f)(); -{ - int niter, rval; - register int i, j; - char *argv[MG_MAXARGC]; - char cntbuf[10]; - /* build partial transformation */ - for (i = 0; i < ac; i++) { - if (av[i][0] == '-' && av[i][1] == 'a' && av[i][2] == '\0') - break; - argv[i+1] = av[i]; - } - argv[i+1] = NULL; - if (i) { /* handle transformation */ - argv[0] = mg_ename[MG_E_XF]; - if ((rval = handle_it(MG_E_XF, i+1, argv)) != MG_OK) - return(rval); - } - if (i < ac) { /* run array */ - if (i+1 >= ac || !isint(av[i+1])) - return(MG_ETYPE); - niter = atoi(av[i+1]); - argv[0] = mg_ename[MG_E_OBJECT]; - argv[1] = cntbuf; - for (j = 2; j+i < ac; j++) - argv[j] = av[j+i]; - argv[j] = NULL; - for (j = 0; j < niter; j++) { - sprintf(cntbuf, "%d", j); - if ((rval = handle_it(MG_E_OBJECT, 2, argv)) != MG_OK) - return(rval); - argv[0] = "-i"; - if ((rval = mg_iterate(ac-i, argv, f)) != MG_OK) - return(rval); - argv[0] = mg_ename[MG_E_OBJECT]; - if ((rval = handle_it(MG_E_OBJECT, 1, argv)) != MG_OK) - return(rval); - } - } else if ((rval = (*f)()) != MG_OK) /* else do this instance */ - return(rval); - if (i) { /* reset the transform */ - argv[0] = mg_ename[MG_E_XF]; - argv[1] = NULL; - (void)handle_it(MG_E_XF, 1, argv); - } - return(MG_OK); -} - - /**************************************************************************** * The following routines handle unsupported entities */ @@ -412,37 +401,42 @@ char **av; static int -reload_file() /* reload current MGF file */ -{ - register int rval; - - if ((rval = mg_rewind()) != MG_OK) - return(rval); - while (mg_read()) - if ((rval = mg_parse()) != MG_OK) - return(rval); - return(MG_OK); -} - - -static int e_include(ac, av) /* include file */ int ac; char **av; { + char *xfarg[MG_MAXARGC]; MG_FCTXT ictx; + XF_SPEC *xf_orig = xf_context; int rv; if (ac < 2) return(MG_EARGC); if ((rv = mg_open(&ictx, av[1])) != MG_OK) return(rv); - if ((rv = mg_iterate(ac-2, av+2, reload_file)) != MG_OK) { - fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname, - ictx.lineno, mg_err[rv], ictx.inpline); - mg_close(); - return(MG_EINCL); + if (ac > 2) { + register int i; + + xfarg[0] = mg_ename[MG_E_XF]; + for (i = 1; i < ac-1; i++) + xfarg[i] = av[i+1]; + xfarg[ac-1] = NULL; + if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) + return(rv); } + do { + while (mg_read()) + if ((rv = mg_parse()) != MG_OK) { + fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname, + ictx.lineno, mg_err[rv], + ictx.inpline); + mg_close(); + return(MG_EINCL); + } + if (ac > 2) + if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) + return(rv); + } while (xf_context != xf_orig); mg_close(); return(MG_OK); } @@ -490,26 +484,26 @@ char **av; rad = atof(av[2]); /* initialize */ warpconends = 1; - if ((rval = handle_it(MG_E_VERTEX, 3, v2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 3, v2ent)) != MG_OK) return(rval); sprintf(p2x, FLTFMT, cv->p[0]); sprintf(p2y, FLTFMT, cv->p[1]); sprintf(p2z, FLTFMT, cv->p[2]+rad); - if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK) return(rval); r2[0] = '0'; r2[1] = '\0'; for (i = 1; i <= 2*mg_nqcdivs; i++) { theta = i*(PI/2)/mg_nqcdivs; - if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rval); sprintf(p2z, FLTFMT, cv->p[2]+rad*cos(theta)); - if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK) return(rval); - if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK) return(rval); strcpy(r1, r2); sprintf(r2, FLTFMT, rad*sin(theta)); - if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK) + if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK) return(rval); } warpconends = 0; @@ -564,26 +558,26 @@ char **av; for (j = 0; j < 3; j++) sprintf(p2[j], FLTFMT, cv->p[j] + .5*sgn*(maxrad-minrad)*cv->n[j]); - if ((rval = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK) return(rval); - if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK) return(rval); sprintf(r2, FLTFMT, avgrad=.5*(minrad+maxrad)); /* run outer section */ for (i = 1; i <= 2*mg_nqcdivs; i++) { theta = i*(PI/2)/mg_nqcdivs; - if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rval); for (j = 0; j < 3; j++) sprintf(p2[j], FLTFMT, cv->p[j] + .5*sgn*(maxrad-minrad)*cos(theta)*cv->n[j]); - if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK) return(rval); - if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK) return(rval); strcpy(r1, r2); sprintf(r2, FLTFMT, avgrad + .5*(maxrad-minrad)*sin(theta)); - if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK) + if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK) return(rval); } /* run inner section */ @@ -593,15 +587,15 @@ char **av; for (j = 0; j < 3; j++) sprintf(p2[j], FLTFMT, cv->p[j] + .5*sgn*(maxrad-minrad)*cos(theta)*cv->n[j]); - if ((rval = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rval); - if ((rval = handle_it(MG_E_VERTEX, 2, v2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_VERTEX, 2, v2ent)) != MG_OK) return(rval); - if ((rval = handle_it(MG_E_POINT, 4, p2ent)) != MG_OK) + if ((rval = mg_handle(MG_E_POINT, 4, p2ent)) != MG_OK) return(rval); strcpy(r1, r2); sprintf(r2, FLTFMT, -avgrad - .5*(maxrad-minrad)*sin(theta)); - if ((rval = handle_it(MG_E_CONE, 5, conent)) != MG_OK) + if ((rval = mg_handle(MG_E_CONE, 5, conent)) != MG_OK) return(rval); } warpconends = 0; @@ -622,7 +616,7 @@ char **av; avnew[2] = av[2]; avnew[3] = av[3]; avnew[4] = av[2]; - return(handle_it(MG_E_CONE, 5, avnew)); + return(mg_handle(MG_E_CONE, 5, avnew)); } @@ -664,59 +658,59 @@ char **av; make_axes(u, v, cv->n); for (j = 0; j < 3; j++) sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*u[j]); - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 3, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); if (minrad == 0.) { /* closed */ v1ent[3] = av[1]; - if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, nzent)) != MG_OK) + if ((rv = mg_handle(MG_E_NORMAL, 4, nzent)) != MG_OK) return(rv); for (i = 1; i <= 4*mg_nqcdivs; i++) { theta = i*(PI/2)/mg_nqcdivs; - if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) sprintf(p3[j], FLTFMT, cv->p[j] + maxrad*u[j]*cos(theta) + maxrad*v[j]*sin(theta)); - if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_FACE, 4, fent)) != MG_OK) + if ((rv = mg_handle(MG_E_FACE, 4, fent)) != MG_OK) return(rv); } } else { /* open */ - if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 3, v4ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) sprintf(p4[j], FLTFMT, cv->p[j] + minrad*u[j]); - if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); v1ent[3] = "_rv4"; for (i = 1; i <= 4*mg_nqcdivs; i++) { theta = i*(PI/2)/mg_nqcdivs; - if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) { d = u[j]*cos(theta) + v[j]*sin(theta); 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, 2, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_FACE, 5, fent)) != MG_OK) + if ((rv = mg_handle(MG_E_FACE, 5, fent)) != MG_OK) return(rv); } } @@ -739,6 +733,7 @@ char **av; static char *p4ent[5] = {mg_ename[MG_E_POINT],p4[0],p4[1],p4[2]}; static char *n4ent[5] = {mg_ename[MG_E_NORMAL],n4[0],n4[1],n4[2]}; static char *fent[6] = {mg_ename[MG_E_FACE],"_cv1","_cv2","_cv3","_cv4"}; + char *v1n; register C_VERTEX *cv1, *cv2; register int i, j; FVECT u, v, w; @@ -754,6 +749,7 @@ char **av; if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); + v1n = av[1]; if (!isflt(av[2]) || !isflt(av[4])) return(MG_ETYPE); rad1 = atof(av[2]); @@ -772,6 +768,7 @@ char **av; cv = cv1; cv1 = cv2; cv2 = cv; + v1n = av[3]; d = rad1; rad1 = rad2; rad2 = d; @@ -798,23 +795,23 @@ char **av; else sprintf(n3[j], FLTFMT, u[j] + w[j]*n2off); } - if ((rv = handle_it(MG_E_VERTEX, 3, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 3, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); if (rad1 == 0.) { /* triangles */ - v1ent[3] = av[1]; - if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + v1ent[3] = v1n; + if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) sprintf(n4[j], FLTFMT, w[j]); - if ((rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK) return(rv); for (i = 1; i <= 4*mg_nqcdivs; i++) { theta = sgn*i*(PI/2)/mg_nqcdivs; - if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) { d = u[j]*cos(theta) + v[j]*sin(theta); @@ -822,14 +819,14 @@ char **av; if (n2off > -FHUGE) sprintf(n3[j], FLTFMT, d + w[j]*n2off); } - if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); if (n2off > -FHUGE && - (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) + (rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_FACE, 4, fent)) != MG_OK) + if ((rv = mg_handle(MG_E_FACE, 4, fent)) != MG_OK) return(rv); } } else { /* quads */ @@ -848,17 +845,17 @@ char **av; else sprintf(n4[j], FLTFMT, u[j] + w[j]*n1off); } - if ((rv = handle_it(MG_E_VERTEX, 3, v4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 3, v4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK) return(rv); for (i = 1; i <= 4*mg_nqcdivs; i++) { theta = sgn*i*(PI/2)/mg_nqcdivs; - if ((rv = handle_it(MG_E_VERTEX, 4, v1ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 4, v2ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 4, v2ent)) != MG_OK) return(rv); for (j = 0; j < 3; j++) { d = u[j]*cos(theta) + v[j]*sin(theta); @@ -869,21 +866,21 @@ char **av; if (n1off < FHUGE) sprintf(n4[j], FLTFMT, d + w[j]*n1off); } - if ((rv = handle_it(MG_E_VERTEX, 2, v3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p3ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p3ent)) != MG_OK) return(rv); if (n2off > -FHUGE && - (rv = handle_it(MG_E_NORMAL, 4, n3ent)) != MG_OK) + (rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_VERTEX, 2, v4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_VERTEX, 2, v4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_POINT, 4, p4ent)) != MG_OK) + if ((rv = mg_handle(MG_E_POINT, 4, p4ent)) != MG_OK) return(rv); if (n1off < FHUGE && - (rv = handle_it(MG_E_NORMAL, 4, n4ent)) != MG_OK) + (rv = mg_handle(MG_E_NORMAL, 4, n4ent)) != MG_OK) return(rv); - if ((rv = handle_it(MG_E_FACE, 5, fent)) != MG_OK) + if ((rv = mg_handle(MG_E_FACE, 5, fent)) != MG_OK) return(rv); } } @@ -897,16 +894,18 @@ int ac; char **av; { static char p[3][24]; - static char *vent[4] = {mg_ename[MG_E_VERTEX],NULL,"="}; + static char *vent[5] = {mg_ename[MG_E_VERTEX],NULL,"="}; static char *pent[5] = {mg_ename[MG_E_POINT],p[0],p[1],p[2]}; + static char *znorm[5] = {mg_ename[MG_E_NORMAL],"0","0","0"}; char *newav[MG_MAXARGC], nvn[MG_MAXARGC-1][8]; double length; + int hasnorm; FVECT v1, v2, v3, norm; register C_VERTEX *cv; C_VERTEX *cv0; int rv; register int i, j; - + /* check arguments */ if (ac < 5) return(MG_EARGC); if (!isflt(av[ac-1])) @@ -914,21 +913,16 @@ char **av; 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 */ + /* 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]; @@ -940,22 +934,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 = handle_it(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 = handle_it(MG_E_POINT, 4, pent)) != MG_OK) + 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 = handle_it(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]; @@ -963,32 +956,97 @@ char **av; 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) + if ((rv = mg_handle(MG_E_FACE, 5, newav)) != MG_OK) return(rv); 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], "%.4f", 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 = handle_it(MG_E_CXY, 3, ccom)) != MG_OK) - return(rv); - } + if (mg_ehand[MG_E_CXY] != c_hcolor) + return(put_cxy()); return(MG_OK); } @@ -998,10 +1056,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 @@ -1012,34 +1066,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 = handle_it(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 = handle_it(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); }