ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/obj2rad.c
(Generate patch)

Comparing ray/src/cv/obj2rad.c (file contents):
Revision 2.3 by greg, Wed Apr 13 14:08:55 1994 UTC vs.
Revision 2.8 by greg, Tue Jun 14 14:30:38 1994 UTC

# Line 7 | Line 7 | static char SCCSid[] = "$SunId$ LBL";
7   /*
8   * Convert a Wavefront .obj file to Radiance format.
9   *
10 < * Currently, we support only polygonal geometry, and faces
11 < * must be either quads or triangles for smoothing to work.
10 > * Currently, we support only polygonal geometry.  Non-planar
11 > * faces are broken rather haphazardly into triangles.
12   * Also, texture map indices only work for triangles, though
13 < * I'm not sure they work correctly.
13 > * I'm not sure they work correctly.  (Taken out -- see TEXMAPS defines.)
14   */
15  
16   #include "standard.h"
# Line 69 | Line 69 | RULEHD *ourmapping = NULL;
69  
70   char    *defmat = DEFMAT;       /* default (starting) material name */
71   char    *defobj = DEFOBJ;       /* default (starting) object name */
72 int     donames = 0;            /* only get qualifier names */
72  
73 + int     flatten = 0;            /* discard surface normal information */
74 +
75   char    *getmtl(), *getonm();
76  
77   char    mapname[128];           /* current picture file */
78   char    matname[64];            /* current material name */
79   char    group[16][32];          /* current group names */
80   char    objname[128];           /* current object name */
81 + char    *inpfile;               /* input file name */
82   int     lineno;                 /* current line number */
83 < int     faceno;                 /* number of faces read */
83 > int     faceno;                 /* current face number */
84  
85  
86   main(argc, argv)                /* read in .obj file and convert */
87   int     argc;
88   char    *argv[];
89   {
90 <        char    *fname;
90 >        int     donames = 0;
91          int     i;
92  
93          for (i = 1; i < argc && argv[i][0] == '-'; i++)
# Line 99 | Line 101 | char   *argv[];
101                  case 'm':               /* use custom mapfile */
102                          ourmapping = getmapping(argv[++i], &qlist);
103                          break;
104 +                case 'f':               /* flatten surfaces */
105 +                        flatten++;
106 +                        break;
107                  default:
108                          goto userr;
109                  }
110          if (i > argc | i < argc-1)
111                  goto userr;
112          if (i == argc)
113 <                fname = "<stdin>";
114 <        else if (freopen(fname=argv[i], "r", stdin) == NULL) {
115 <                fprintf(stderr, "%s: cannot open\n", fname);
113 >                inpfile = "<stdin>";
114 >        else if (freopen(inpfile=argv[i], "r", stdin) == NULL) {
115 >                fprintf(stderr, "%s: cannot open\n", inpfile);
116                  exit(1);
117          }
118          if (donames) {                          /* scan for ids */
119                  getnames(stdin);
120 <                printf("filename \"%s\"\n", fname);
120 >                printf("filename \"%s\"\n", inpfile);
121                  printf("filetype \"Wavefront\"\n");
122                  write_quals(&qlist, qual, stdout);
123                  printf("qualifier %s begin\n", qlist.qual[Q_FAC]);
# Line 121 | Line 126 | char   *argv[];
126          } else {                                /* translate file */
127                  printf("# ");
128                  printargs(argc, argv, stdout);
129 <                convert(fname, stdin);
129 >                convert(stdin);
130          }
131          exit(0);
132   userr:
# Line 180 | Line 185 | FILE   *fp;
185   }
186  
187  
188 < convert(fname, fp)              /* convert a T-mesh */
184 < char    *fname;
188 > convert(fp)                     /* convert a T-mesh */
189   FILE    *fp;
190   {
191          char    *argv[MAXARG];
192          int     argc;
193          int     nstats, nunknown;
194          register int    i;
195 <                                        /* start fresh */
192 <        freeverts();
193 <        mapname[0] = '\0';
194 <        strcpy(matname, defmat);
195 <        strcpy(objname, defobj);
196 <        lineno = 0;
195 >
196          nstats = nunknown = 0;
197                                          /* scan until EOF */
198          while (argc = getstmt(argv, fp)) {
# Line 202 | Line 201 | FILE   *fp;
201                          switch (argv[0][1]) {
202                          case '\0':                      /* point */
203                                  if (badarg(argc-1,argv+1,"fff"))
204 <                                        syntax(fname, lineno, "Bad vertex");
204 >                                        syntax("Bad vertex");
205                                  newv(atof(argv[1]), atof(argv[2]),
206                                                  atof(argv[3]));
207                                  break;
# Line 210 | Line 209 | FILE   *fp;
209                                  if (argv[0][2])
210                                          goto unknown;
211                                  if (badarg(argc-1,argv+1,"fff"))
212 <                                        syntax(fname, lineno, "Bad normal");
212 >                                        syntax("Bad normal");
213                                  if (!newvn(atof(argv[1]), atof(argv[2]),
214                                                  atof(argv[3])))
215 <                                        syntax(fname, lineno, "Zero normal");
215 >                                        syntax("Zero normal");
216                                  break;
217                          case 't':                       /* texture map */
218                                  if (argv[0][2])
# Line 232 | Line 231 | FILE   *fp;
231                          faceno++;
232                          switch (argc-1) {
233                          case 0: case 1: case 2:
234 <                                syntax(fname, lineno, "Too few vertices");
234 >                                syntax("Too few vertices");
235                                  break;
236                          case 3:
237                                  if (!puttri(argv[1], argv[2], argv[3]))
238 <                                        syntax(fname, lineno, "Bad triangle");
238 >                                        syntax("Bad triangle");
239                                  break;
240                          case 4:
241                                  if (!putquad(argv[1], argv[2],
242                                                  argv[3], argv[4]))
243 <                                        syntax(fname, lineno, "Bad quad");
243 >                                        syntax("Bad quad");
244                                  break;
245                          default:
246                                  if (!putface(argc-1, argv+1))
247 <                                        syntax(fname, lineno, "Bad face");
247 >                                        syntax("Bad face");
248                                  break;
249                          }
250                          break;
# Line 260 | Line 259 | FILE   *fp;
259                                  if (!strcmp(argv[1], "off"))
260                                          mapname[0] = '\0';
261                                  else
262 <                                        strcpy(mapname, argv[1]);
262 >                                        sprintf(mapname, "%s.pic", argv[1]);
263                          } else
264                                  goto unknown;
265                          break;
# Line 279 | Line 278 | FILE   *fp;
278                          group[i-1][0] = '\0';
279                          break;
280                  case '#':               /* comment */
281 +                        printargs(argc, argv, stdout);
282                          break;
283                  default:;               /* something we don't deal with */
284                  unknown:
# Line 287 | Line 287 | FILE   *fp;
287                  }
288                  nstats++;
289          }
290 <        printf("\n# Done processing file: %s\n", fname);
290 >        printf("\n# Done processing file: %s\n", inpfile);
291          printf("# %d lines, %d statements, %d unrecognized\n",
292                          lineno, nstats, nunknown);
293   }
# Line 332 | Line 332 | getmtl()                               /* figure material for this face */
332   {
333          register RULEHD *rp = ourmapping;
334  
335 <        if (rp == NULL)                 /* no rule set */
336 <                return(matname);
335 >        if (rp == NULL) {               /* no rule set */
336 >                if (matname[0])
337 >                        return(matname);
338 >                if (group[0][0])
339 >                        return(group[0]);
340 >                return(defmat);
341 >        }
342                                          /* check for match */
343          do {
344                  if (matchrule(rp)) {
# Line 354 | Line 359 | getonm()                               /* invent a good name for object */
359          static char     name[64];
360          register char   *cp1, *cp2;
361          register int    i;
362 <
363 <        if (!group[0][0] || strcmp(objname, DEFOBJ))
364 <                return(objname);        /* good enough for us */
365 <
362 >                                        /* check for preset */
363 >        if (objname[0])
364 >                return(objname);
365 >        if (!group[0][0])
366 >                return(defobj);
367          cp1 = name;                     /* else make name out of groups */
368          for (i = 0; group[i][0]; i++) {
369                  cp2 = group[i];
# Line 381 | Line 387 | register RULEHD        *rp;
387          register int    i;
388  
389          if (rp->qflg & FL(Q_MTL)) {
390 +                if (!matname[0])
391 +                        return(0);
392                  tmpid.number = 0;
393                  tmpid.name = matname;
394                  if (!matchid(&tmpid, &idm(rp)[Q_MTL]))
395                          return(0);
396          }
397          if (rp->qflg & FL(Q_MAP)) {
398 +                if (!mapname[0])
399 +                        return(0);
400                  tmpid.number = 0;
401                  tmpid.name = mapname;
402                  if (!matchid(&tmpid, &idm(rp)[Q_MAP]))
# Line 403 | Line 413 | register RULEHD        *rp;
413                          return(0);
414          }
415          if (rp->qflg & FL(Q_OBJ)) {
416 +                if (!objname[0])
417 +                        return(0);
418                  tmpid.number = 0;
419                  tmpid.name = objname;
420                  if (!matchid(&tmpid, &idm(rp)[Q_OBJ]))
# Line 465 | Line 477 | register char  *vs;
477   }
478  
479  
480 < putface(ac, av)                         /* put out an N-sided polygon */
480 > nonplanar(ac, av)                       /* are vertices are non-planar? */
481   register int    ac;
482   register char   **av;
483   {
484          VNDX    vi;
485 <        char    *mod;
485 >        FLOAT   *p0, *p1;
486 >        FVECT   v1, v2, nsum, newn;
487 >        double  d;
488 >        register int    i;
489  
490 <        if ((mod = getmtl()) == NULL)
490 >        if (!cvtndx(vi, av[0]))
491 >                return(0);
492 >        if (vi[2] >= 0)
493 >                return(1);              /* has interpolated normals */
494 >        if (ac < 4)
495 >                return(0);              /* it's a triangle! */
496 >                                        /* set up */
497 >        p0 = vlist[vi[0]];
498 >        if (!cvtndx(vi, av[1]))
499 >                return(0);              /* error gets caught later */
500 >        nsum[0] = nsum[1] = nsum[2] = 0.;
501 >        p1 = vlist[vi[0]];
502 >        fvsum(v2, p1, p0, -1.0);
503 >        for (i = 2; i < ac; i++) {
504 >                VCOPY(v1, v2);
505 >                if (!cvtndx(vi, av[i]))
506 >                        return(0);
507 >                p1 = vlist[vi[0]];
508 >                fvsum(v2, p1, p0, -1.0);
509 >                fcross(newn, v1, v2);
510 >                if (normalize(newn) == 0.0) {
511 >                        if (i < 3)
512 >                                return(1);      /* can't deal with this */
513 >                        fvsum(nsum, nsum, nsum, 1./(i-2));
514 >                        continue;
515 >                }
516 >                d = fdot(newn,nsum);
517 >                if (d >= 0) {
518 >                        if (d < (1.0-FTINY)*(i-2))
519 >                                return(1);
520 >                        fvsum(nsum, nsum, newn, 1.0);
521 >                } else {
522 >                        if (d > -(1.0-FTINY)*(i-2))
523 >                                return(1);
524 >                        fvsum(nsum, nsum, newn, -1.0);
525 >                }
526 >        }
527 >        return(0);
528 > }
529 >
530 >
531 > putface(ac, av)                         /* put out an N-sided polygon */
532 > int     ac;
533 > register char   **av;
534 > {
535 >        VNDX    vi;
536 >        char    *cp;
537 >        register int    i;
538 >
539 >        if (nonplanar(ac, av)) {        /* break into quads and triangles */
540 >                while (ac > 3) {
541 >                        if (!putquad(av[0], av[1], av[2], av[3]))
542 >                                return(0);
543 >                        ac -= 2;        /* remove two vertices & rotate */
544 >                        cp = av[0];
545 >                        for (i = 0; i < ac-1; i++)
546 >                                av[i] = av[i+3];
547 >                        av[i] = cp;
548 >                }
549 >                if (ac == 3 && !puttri(av[0], av[1], av[2]))
550 >                        return(0);
551 >                return(1);
552 >        }
553 >        if ((cp = getmtl()) == NULL)
554                  return(-1);
555 <        printf("\n%s polygon %s.%d\n", mod, getonm(), faceno);
555 >        printf("\n%s polygon %s.%d\n", cp, getonm(), faceno);
556          printf("0\n0\n%d\n", 3*ac);
557 <        while (ac--) {
558 <                if (!cvtndx(vi, *av++))
557 >        for (i = 0; i < ac; i++) {
558 >                if (!cvtndx(vi, av[i]))
559                          return(0);
560                  pvect(vlist[vi[0]]);
561          }
# Line 499 | Line 577 | char   *v1, *v2, *v3;
577          if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3))
578                  return(0);
579                                          /* compute barycentric coordinates */
580 <        texOK = (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0);
580 >        texOK = !flatten && (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0);
581 > #ifdef TEXMAPS
582          patOK = mapname[0] && (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0);
583 + #else
584 +        patOK = 0;
585 + #endif
586          if (texOK | patOK)
587                  if (comp_baryc(bvecs, vlist[v1i[0]], vlist[v2i[0]],
588                                  vlist[v3i[0]]) < 0)
# Line 522 | Line 604 | char   *v1, *v2, *v3;
604                                  vnlist[v1i[2]][2], vnlist[v2i[2]][2],
605                                  vnlist[v3i[2]][2]);
606          }
607 + #ifdef TEXMAPS
608                                          /* put out pattern (if any) */
609          if (patOK) {
610                  printf("\n%s colorpict %s\n", mod, PATNAME);
# Line 534 | Line 617 | char   *v1, *v2, *v3;
617                  printf("\t%f %f %f\n", vtlist[v1i[1]][1],
618                                  vtlist[v2i[1]][1], vtlist[v3i[1]][1]);
619          }
620 + #endif
621                                          /* put out triangle */
622          printf("\n%s polygon %s.%d\n", mod, getonm(), faceno);
623          printf("0\n0\n9\n");
# Line 595 | Line 679 | register BARYCCM       bcm;
679   }
680  
681  
682 < putquad(p0, p1, p2, p3)                 /* put out a quadrilateral */
683 < char  *p0, *p1, *p2, *p3;
682 > putquad(p0, p1, p3, p2)                 /* put out a quadrilateral */
683 > char  *p0, *p1, *p3, *p2;               /* names correspond to binary pos. */
684   {
685          VNDX  p0i, p1i, p2i, p3i;
686          FVECT  norm[4];
# Line 605 | Line 689 | char  *p0, *p1, *p2, *p3;
689          FVECT  v1, v2, vc1, vc2;
690          int  ok1, ok2;
691  
692 + #ifdef TEXMAPS
693 +        /* also should output texture index coordinates,
694 +         * which will require new .cal file
695 +         */
696 + #endif
697          if ((mod = getmtl()) == NULL)
698                  return(-1);
699          name = getonm();
# Line 627 | Line 716 | char  *p0, *p1, *p2, *p3;
716          axis = norminterp(norm, p0i, p1i, p2i, p3i);
717  
718                                          /* put out quadrilateral? */
719 <        if (ok1 & ok2 && fdot(vc1,vc2) >= 1.0-FTINY*FTINY) {
719 >        if (ok1 & ok2 && fabs(fdot(vc1,vc2)) >= 1.0-FTINY) {
720                  printf("\n%s ", mod);
721                  if (axis != -1) {
722                          printf("texfunc %s\n", TEXNAME);
# Line 705 | Line 794 | register VNDX  p0i, p1i, p2i, p3i;
794          FVECT  v1;
795          register int  i, j;
796  
797 <        if (!(p0i[2]>=0 && p1i[2]>=0 && p2i[2]>=0 && p3i[2]>=0))
797 > #ifdef TEXMAPS
798 >        /* also check for texture indices */
799 > #endif
800 >        if (flatten || !(p0i[2]>=0 && p1i[2]>=0 && p2i[2]>=0 && p3i[2]>=0))
801                  return(-1);
802                                          /* find dominant axis */
803          VCOPY(v1, vnlist[p0i[2]]);
# Line 741 | Line 833 | register VNDX  p0i, p1i, p2i, p3i;
833                                          eqnmat[j][1]*vnlist[p1i[2]][i] +
834                                          eqnmat[j][2]*vnlist[p2i[2]][i] +
835                                          eqnmat[j][3]*vnlist[p3i[2]][i];
836 + #ifdef TEXMAPS
837 +        /* compute result matrix for texture indices */
838 + #endif
839          return(ax);
840  
841   #undef u
# Line 839 | Line 934 | double x, y;
934   }
935  
936  
937 < syntax(fn, ln, er)                      /* report syntax error and exit */
843 < char    *fn;
844 < int     ln;
937 > syntax(er)                      /* report syntax error and exit */
938   char    *er;
939   {
940          fprintf(stderr, "%s: Wavefront syntax error near line %d: %s\n",
941 <                        fn, ln, er);
941 >                        inpfile, lineno, er);
942          exit(1);
943   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines