int r_face( /* convert a face */ int ac, char **av ) { static int nfaces; int myi = invert; char *mat; register int i; register C_VERTEX *cv; FVECT v; /* check argument count and type */ if (ac < 4) return(MG_EARGC); if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); if (ac <= 5) { /* check for smoothing */ C_VERTEX *cva[5]; for (i = 1; i < ac; i++) { if ((cva[i-1] = c_getvert(av[i])) == NULL) return(MG_EUNDEF); if (is0vect(cva[i-1]->n)) break; } if (i < ac) i = ISFLAT; else i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p, cva[0]->n, cva[1]->n, cva[2]->n); if (i == DEGEN) return(MG_OK); /* degenerate (error?) */ if (i == RVBENT) { myi = !myi; i = ISBENT; } else if (i == RVFLAT) { myi = !myi; i = ISFLAT; } if (i == ISBENT) { /* smoothed triangles */ do_tri(mat, cva[0], cva[1], cva[2], myi); if (ac == 5) do_tri(mat, cva[2], cva[3], cva[0], myi); return(MG_OK); } } /* spit out unsmoothed primitive */ printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces); printf("0\n0\n%d\n", 3*(ac-1)); for (i = 1; i < ac; i++) { /* get, transform, print each vertex */ if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL) return(MG_EUNDEF); xf_xfmpoint(v, cv->p); putv(v); } return(MG_OK); }
int r_sph( /* put out a sphere */ int ac, char **av ) { static int nsphs; char *mat; double rad; C_VERTEX *cv; FVECT cent; int inv; /* check argument count and type */ if (ac != 3) return(MG_EARGC); if (!isflt(av[2])) return(MG_ETYPE); if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */ return(MG_EUNDEF); xf_xfmpoint(cent, cv->p); /* transform center */ rad = xf_scale(atof(av[2])); /* scale radius */ if ((inv = rad < 0.)) /* check for inversion */ rad = -rad; if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out primitive */ printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere", object(), ++nsphs); printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n", cent[0], cent[1], cent[2], rad); return(MG_OK); }
int i_sph( /* translate sphere description */ int ac, char **av ) { register C_VERTEX *cent; if (ac != 3) return(MG_EARGC); flush_cache(); /* flush vertex cache */ printf("%sSeparator {\n", tabs); indent(1); /* put out current material */ if (put_material() < 0) return(MG_EBADMAT); /* get center */ if ((cent = c_getvert(av[1])) == NULL) return(MG_EUNDEF); /* get radius */ if (!isflt(av[2])) return(MG_ETYPE); printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, cent->p[0], cent->p[1], cent->p[2]); printf("%sSphere { radius %s }\n", tabs, av[2]); indent(0); printf("%s}\n", tabs); return(MG_OK); }
int r_cone( /* put out a cone */ int ac, char **av ) { static int ncones; char *mat; double r1, r2; C_VERTEX *cv1, *cv2; FVECT p1, p2; int inv; /* check argument count and type */ if (ac != 5) return(MG_EARGC); if (!isflt(av[2]) || !isflt(av[4])) return(MG_ETYPE); /* get the endpoint vertices */ if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); xf_xfmpoint(p1, cv1->p); /* transform endpoints */ xf_xfmpoint(p2, cv2->p); r1 = xf_scale(atof(av[2])); /* scale radii */ r2 = xf_scale(atof(av[4])); inv = r1 < 0.; /* check for inverted cone */ if (r1 == 0.) { /* check for illegal radii */ if (r2 == 0.) return(MG_EILL); inv = r2 < 0.; } else if (r2 != 0. && inv ^ (r2 < 0.)) return(MG_EILL); if (inv) { r1 = -r1; r2 = -r2; } if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit the sucker out */ printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone", object(), ++ncones); printf("0\n0\n8\n"); putv(p1); putv(p2); printf("%18.12g %18.12g\n", r1, r2); return(MG_OK); }
int i_cyl( /* translate a cylinder description */ int ac, char **av ) { register C_VERTEX *v1, *v2; FVECT va; double length, angle; if (ac != 4) return(MG_EARGC); flush_cache(); /* flush vertex cache */ printf("%sSeparator {\n", tabs); indent(1); /* put out current material */ if (put_material() < 0) return(MG_EBADMAT); /* get endpoints */ if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL)) return(MG_EUNDEF); /* get radius */ if (!isflt(av[2])) return(MG_ETYPE); /* compute transform */ va[0] = v2->p[0] - v1->p[0]; va[1] = v2->p[1] - v1->p[1]; va[2] = v2->p[2] - v1->p[2]; length = VLEN(va); angle = Acos(va[1]/length); printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs, .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]), .5*(v1->p[2]+v2->p[2])); printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs, va[2], 0., -va[0], angle); /* open-ended */ printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs, length, av[2]); indent(0); printf("%s}\n", tabs); return(MG_OK); }
int r_cyl( /* put out a cylinder */ int ac, char **av ) { static int ncyls; char *mat; double rad; C_VERTEX *cv1, *cv2; FVECT p1, p2; int inv; /* check argument count and type */ if (ac != 4) return(MG_EARGC); if (!isflt(av[2])) return(MG_ETYPE); /* get the endpoint vertices */ if ((cv1 = c_getvert(av[1])) == NULL || (cv2 = c_getvert(av[3])) == NULL) return(MG_EUNDEF); xf_xfmpoint(p1, cv1->p); /* transform endpoints */ xf_xfmpoint(p2, cv2->p); rad = xf_scale(atof(av[2])); /* scale radius */ if ((inv = rad < 0.)) /* check for inverted cylinder */ rad = -rad; if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out the primitive */ printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder", object(), ++ncyls); printf("0\n0\n7\n"); putv(p1); putv(p2); printf("%18.12g\n", rad); return(MG_OK); }
int i_face( /* translate an N-sided face */ int ac, char **av ) { static char lastmat[MAXID]; struct face *newf; register C_VERTEX *vp; register LUENT *lp; register int i; if (ac < 4) return(MG_EARGC); if ( strcmp(lastmat, curmatname) || c_cmaterial->clock || nverts == 0 || nverts+ac-1 >= MAXVERT) { flush_cache(); /* new cache */ lu_init(&vert_tab, MAXVERT); printf("%sSeparator {\n", tabs); indent(1); if (put_material() < 0) /* put out material */ return(MG_EBADMAT); (void)strcpy(lastmat, curmatname); } /* allocate new face */ if ((newf = newface(ac-1)) == NULL) return(MG_EMEM); newf->nv = ac-1; /* get vertex references */ for (i = 0; i < newf->nv; i++) { if ((vp = c_getvert(av[i+1])) == NULL) return(MG_EUNDEF); setvkey(vlist[nverts], vp); lp = lu_find(&vert_tab, vlist[nverts]); if (lp == NULL) return(MG_EMEM); if (lp->key == NULL) lp->key = (char *)vlist[nverts++]; newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist); } /* add to face list */ newf->next = NULL; if (flist == NULL) flist = newf; else flast->next = newf; flast = newf; return(MG_OK); /* we'll actually put it out later */ }
int r_ring( /* put out a ring */ int ac, char **av ) { static int nrings; char *mat; double r1, r2; C_VERTEX *cv; FVECT cent, norm; /* check argument count and type */ if (ac != 4) return(MG_EARGC); if (!isflt(av[2]) || !isflt(av[3])) return(MG_ETYPE); if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */ return(MG_EUNDEF); if (is0vect(cv->n)) /* make sure we have normal */ return(MG_EILL); xf_xfmpoint(cent, cv->p); /* transform center */ xf_rotvect(norm, cv->n); /* rotate normal */ r1 = xf_scale(atof(av[2])); /* scale radii */ r2 = xf_scale(atof(av[3])); if ((r1 < 0.) | (r2 <= r1)) return(MG_EILL); if ((mat = material()) == NULL) /* get material */ return(MG_EBADMAT); /* spit out primitive */ printf("\n%s ring %sr%d\n", mat, object(), ++nrings); printf("0\n0\n8\n"); putv(cent); putv(norm); printf("%18.12g %18.12g\n", r1, r2); return(MG_OK); }