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); }
void triangle( /* put out a triangle */ char *pn, char *mod, char *obj, VERTEX *v1, VERTEX *v2, VERTEX *v3 ) { static char vfmt[] = "%18.12g %18.12g %18.12g\n"; static int ntri = 0; int flatness = ISFLAT; BARYCCM bvecs; RREAL bvm[3][3]; int i; /* compute barycentric coordinates */ if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM)) if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0) return; /* check flatness */ if (v1->flags & v2->flags & v3->flags & V_HASNORM) { flatness = flat_tri(v1->pos, v2->pos, v3->pos, v1->nor, v2->nor, v3->nor); if (flatness == DEGEN) return; } /* put out texture (if any) */ if (flatness == ISBENT || flatness == RVBENT) { printf("\n%s texfunc %s\n", mod, TEXNAME); mod = TEXNAME; printf("4 dx dy dz %s\n", TCALNAME); printf("0\n"); for (i = 0; i < 3; i++) { bvm[i][0] = v1->nor[i]; bvm[i][1] = v2->nor[i]; bvm[i][2] = v3->nor[i]; } put_baryc(&bvecs, bvm, 3); } /* put out pattern (if any) */ if (*pn && (v1->flags & v2->flags & v3->flags & V_HASINDX)) { printf("\n%s colorpict %s\n", mod, PATNAME); mod = PATNAME; printf("7 noneg noneg noneg %s %s u v\n", pn, TCALNAME); printf("0\n"); for (i = 0; i < 2; i++) { bvm[i][0] = v1->ndx[i]; bvm[i][1] = v2->ndx[i]; bvm[i][2] = v3->ndx[i]; } put_baryc(&bvecs, bvm, 2); } /* put out (reversed) triangle */ printf("\n%s polygon %s.%d\n", mod, obj, ++ntri); printf("0\n0\n9\n"); if (flatness == RVFLAT || flatness == RVBENT) { printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]); printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]); printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]); } else { printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]); printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]); printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]); } }
int /* create an extended triangle */ cvtri( OBJECT mo, FVECT vp1, FVECT vp2, FVECT vp3, FVECT vn1, FVECT vn2, FVECT vn3, RREAL vc1[2], RREAL vc2[2], RREAL vc3[2] ) { static OBJECT fobj = OVOID; char buf[32]; int flags; TRIDATA *ts; FACE *f; OBJREC *fop; int j; flags = MT_V; /* check what we have */ if (vn1 != NULL && vn2 != NULL && vn3 != NULL) { RREAL *rp; switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) { case ISBENT: flags |= MT_N; /* fall through */ case ISFLAT: break; case RVBENT: flags |= MT_N; rp = vn1; vn1 = vn3; vn3 = rp; /* fall through */ case RVFLAT: rp = vp1; vp1 = vp3; vp3 = rp; rp = vc1; vc1 = vc3; vc3 = rp; break; case DEGEN: error(WARNING, "degenerate triangle"); return(0); default: error(INTERNAL, "bad return from flat_tri()"); } } if (vc1 != NULL && vc2 != NULL && vc3 != NULL) flags |= MT_UV; if (fobj == OVOID) { /* create new triangle object */ fobj = newobject(); if (fobj == OVOID) goto nomem; fop = objptr(fobj); fop->omod = mo; fop->otype = OBJ_FACE; sprintf(buf, "t%ld", (long)fobj); fop->oname = savqstr(buf); fop->oargs.nfargs = 9; fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL)); if (fop->oargs.farg == NULL) goto nomem; } else { /* else reuse failed one */ fop = objptr(fobj); if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9) error(CONSISTENCY, "code error 1 in cvtri"); } for (j = 3; j--; ) { fop->oargs.farg[j] = vp1[j]; fop->oargs.farg[3+j] = vp2[j]; fop->oargs.farg[6+j] = vp3[j]; } /* create face record */ f = getface(fop); if (f->area == 0.) { free_os(fop); return(0); } if (fop->os != (char *)f) error(CONSISTENCY, "code error 2 in cvtri"); /* follow with auxliary data */ f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags)); if (f == NULL) goto nomem; fop->os = (char *)f; ts = (TRIDATA *)(f+1); ts->fl = flags; ts->obj = OVOID; if (flags & MT_N) for (j = 3; j--; ) { ts->vn[0][j] = vn1[j]; ts->vn[1][j] = vn2[j]; ts->vn[2][j] = vn3[j]; } if (flags & MT_UV) for (j = 2; j--; ) { ts->vc[0][j] = vc1[j]; ts->vc[1][j] = vc2[j]; ts->vc[2][j] = vc3[j]; } else vc1 = vc2 = vc3 = NULL; /* update bounds */ add2bounds(vp1, vc1); add2bounds(vp2, vc2); add2bounds(vp3, vc3); fobj = OVOID; /* we used this one */ return(1); nomem: error(SYSTEM, "out of memory in cvtri"); return(0); }
int puttri( /* put out a triangle */ char *v1, char *v2, char *v3 ) { char *mod; VNDX v1i, v2i, v3i; BARYCCM bvecs; RREAL bcoor[3][3]; int texOK = 0, patOK; int flatness; int i; if ((mod = getmtl()) == NULL) return(-1); if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) return(0); /* compute barycentric coordinates */ if (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0) flatness = flat_tri(vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]], vnlist[v1i[2]], vnlist[v2i[2]], vnlist[v3i[2]]); else flatness = ISFLAT; switch (flatness) { case DEGEN: /* zero area */ ndegen++; return(-1); case RVFLAT: /* reversed normals, but flat */ case ISFLAT: /* smoothing unnecessary */ texOK = 0; break; case RVBENT: /* reversed normals with smoothing */ case ISBENT: /* proper smoothing */ texOK = 1; break; } if (flatten) texOK = 0; #ifdef TEXMAPS patOK = mapname[0] && (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0); #else patOK = 0; #endif if (texOK | patOK) if (comp_baryc(&bvecs, vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]]) < 0) texOK = patOK = 0; /* put out texture (if any) */ if (texOK) { printf("\n%s texfunc %s\n", mod, TEXNAME); mod = TEXNAME; printf("4 dx dy dz %s\n", TCALNAME); printf("0\n"); for (i = 0; i < 3; i++) { bcoor[i][0] = vnlist[v1i[2]][i]; bcoor[i][1] = vnlist[v2i[2]][i]; bcoor[i][2] = vnlist[v3i[2]][i]; } put_baryc(&bvecs, bcoor, 3); } #ifdef TEXMAPS /* put out pattern (if any) */ if (patOK) { printf("\n%s colorpict %s\n", mod, PATNAME); mod = PATNAME; printf("7 noneg noneg noneg %s %s u v\n", mapname, TCALNAME); printf("0\n"); for (i = 0; i < 2; i++) { bcoor[i][0] = vtlist[v1i[1]][i]; bcoor[i][1] = vtlist[v2i[1]][i]; bcoor[i][2] = vtlist[v3i[1]][i]; } put_baryc(&bvecs, bcoor, 2); } #endif /* put out (reversed) triangle */ printf("\n%s polygon %s.%d\n", mod, getonm(), faceno); printf("0\n0\n9\n"); if (flatness == RVFLAT || flatness == RVBENT) { pvect(vlist[v3i[0]]); pvect(vlist[v2i[0]]); pvect(vlist[v1i[0]]); } else { pvect(vlist[v1i[0]]); pvect(vlist[v2i[0]]); pvect(vlist[v3i[0]]); } return(1); }