int putface( /* put out an N-sided polygon */ int ac, char **av ) { VNDX vi; char *cp; int i; if (nonplanar(ac, av)) { /* break into triangles */ while (ac > 2) { if (!puttri(av[0], av[1], av[2])) return(0); ac--; /* remove vertex & rotate */ cp = av[0]; for (i = 0; i < ac-1; i++) av[i] = av[i+2]; av[i] = cp; } return(1); } if ((cp = getmtl()) == NULL) return(-1); printf("\n%s polygon %s.%d\n", cp, getonm(), faceno); printf("0\n0\n%d\n", 3*ac); for (i = 0; i < ac; i++) { if (!cvtndx(vi, av[i])) return(0); pvect(vlist[vi[0]]); } return(1); }
/* callback for triangle output from polygon */ static int tri_out(const Vert2_list *tp, int a, int b, int c) { return( puttri( ((char **)tp->p)[a], ((char **)tp->p)[b], ((char **)tp->p)[c] ) ); }
void wfreadobj( /* read in .OBJ file and convert */ char *objfn ) { FILE *fp; char *argv[MAXARG]; int argc; int nstats, nunknown; if (objfn == NULL) { inpfile = "<stdin>"; fp = stdin; } else if ((fp = fopen(inpfile=objfn, "r")) == NULL) { sprintf(errmsg, "cannot open \"%s\"", inpfile); error(USER, errmsg); } havemats = (nobjects > 0); nstats = nunknown = 0; material[0] = '\0'; group[0] = '\0'; lineno = 0; faceno = 0; /* scan until EOF */ while ( (argc = getstmt(argv, fp)) ) { switch (argv[0][0]) { case 'v': /* vertex */ switch (argv[0][1]) { case '\0': /* point */ if (badarg(argc-1,argv+1,"fff")) syntax("bad vertex"); newv(atof(argv[1]), atof(argv[2]), atof(argv[3])); break; case 'n': /* normal */ if (argv[0][2]) goto unknown; if (badarg(argc-1,argv+1,"fff")) syntax("bad normal"); if (!newvn(atof(argv[1]), atof(argv[2]), atof(argv[3]))) syntax("zero normal"); break; case 't': /* coordinate */ if (argv[0][2]) goto unknown; if (badarg(argc-1,argv+1,"ff")) goto unknown; newvt(atof(argv[1]), atof(argv[2])); break; default: goto unknown; } break; case 'f': /* face */ if (argv[0][1]) goto unknown; faceno++; switch (argc-1) { case 0: case 1: case 2: syntax("too few vertices"); break; case 3: if (!puttri(argv[1], argv[2], argv[3])) syntax("bad triangle"); break; default: if (!putface(argc-1, argv+1)) syntax("bad face"); break; } break; case 'u': /* usemtl/usemap */ if (!strcmp(argv[0], "usemap")) break; if (strcmp(argv[0], "usemtl")) goto unknown; if (argc > 1) strcpy(material, argv[1]); else material[0] = '\0'; break; case 'o': /* object name */ if (argv[0][1]) goto unknown; break; case 'g': /* group name */ if (argv[0][1]) goto unknown; if (argc > 1) strcpy(group, argv[1]); else group[0] = '\0'; break; case '#': /* comment */ break; default:; /* something we don't deal with */ unknown: nunknown++; break; } nstats++; } /* clean up */ freeverts(); fclose(fp); if (nunknown > 0) { sprintf(errmsg, "%d of %d statements unrecognized", nunknown, nstats); error(WARNING, errmsg); } }
void convert( /* convert an OBJ stream */ FILE *fp ) { char *argv[MAXARG]; int argc; int nstats, nunknown; int i; nstats = nunknown = 0; /* scan until EOF */ while ( (argc = getstmt(argv, fp)) ) { switch (argv[0][0]) { case 'v': /* vertex */ switch (argv[0][1]) { case '\0': /* point */ if (badarg(argc-1,argv+1,"fff")) syntax("Bad vertex"); newv(atof(argv[1]), atof(argv[2]), atof(argv[3])); break; case 'n': /* normal */ if (argv[0][2]) goto unknown; if (badarg(argc-1,argv+1,"fff")) syntax("Bad normal"); if (!newvn(atof(argv[1]), atof(argv[2]), atof(argv[3]))) syntax("Zero normal"); break; case 't': /* texture map */ if (argv[0][2]) goto unknown; if (badarg(argc-1,argv+1,"ff")) goto unknown; newvt(atof(argv[1]), atof(argv[2])); break; default: goto unknown; } break; case 'f': /* face */ if (argv[0][1]) goto unknown; faceno++; switch (argc-1) { case 0: case 1: case 2: syntax("Too few vertices"); break; case 3: if (!puttri(argv[1], argv[2], argv[3])) syntax("Bad triangle"); break; default: if (!putface(argc-1, argv+1)) syntax("Bad face"); break; } break; case 'u': if (!strcmp(argv[0], "usemtl")) { /* material */ if (argc < 2) break; /* not fatal */ strcpy(matname, argv[1]); } else if (!strcmp(argv[0], "usemap")) {/* map */ if (argc < 2) break; /* not fatal */ if (!strcmp(argv[1], "off")) mapname[0] = '\0'; else sprintf(mapname, "%s.hdr", argv[1]); } else goto unknown; break; case 'o': /* object name */ if (argv[0][1]) goto unknown; if (argc < 2) break; /* not fatal */ strcpy(objname, argv[1]); break; case 'g': /* group name(s) */ if (argv[0][1]) goto unknown; for (i = 1; i < argc; i++) strcpy(group[i-1], argv[i]); group[argc-1][0] = '\0'; break; case '#': /* comment */ printargs(argc, argv, stdout); break; default:; /* something we don't deal with */ unknown: nunknown++; break; } nstats++; } printf("\n# Done processing file: %s\n", inpfile); printf("# %d lines, %d statements, %d unrecognized\n", lineno, nstats, nunknown); }