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

Comparing ray/src/cv/mgflib/mgf2inv.c (file contents):
Revision 1.1 by greg, Mon Dec 4 09:59:57 1995 UTC vs.
Revision 1.5 by greg, Wed Feb 5 14:53:33 1997 UTC

# Line 14 | Line 14 | static char SCCSid[] = "$SunId$ LBL";
14  
15   #include <math.h>
16  
17 + #include <ctype.h>
18 +
19   #include "parser.h"
20  
21   #include "lookup.h"
22  
23 < #ifndef PI
24 < #define PI              3.14159265358979323846
25 < #endif
23 > #define O_INV1          1       /* Inventor 1.0 output */
24 > #define O_INV2          2       /* Inventor 2.0 output */
25 > #define O_VRML          3       /* VRML output */
26  
27 + #define MAXID           48      /* maximum identifier length */
28 +
29 + #define VERTFMT         "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f"
30 + #define VZVECT          "+0.000 +0.000 +0.000"
31 + #define VFSEPPOS        50      /* position of newline in above */
32 + #define VFLEN           72      /* total vertex string length */
33 + #define MAXVERT         10240   /* maximum cached vertices */
34 +
35 + #define setvkey(k,v)    sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\
36 +                                        (v)->n[0],(v)->n[1],(v)->n[2]);
37 +
38 + char    vlist[MAXVERT][VFLEN];  /* our vertex cache */
39 + int     nverts;                 /* current cache size */
40 +
41 + LUTAB   vert_tab = LU_SINIT(NULL,NULL);
42 +
43 + struct face {
44 +        struct face     *next;          /* next face in list */
45 +        short           nv;             /* number of vertices */
46 +        short           vl[3];          /* vertex index list (variable) */
47 + }       *flist, *flast;         /* our face cache */
48 +
49 + #define newface(n)      (struct face *)malloc(sizeof(struct face) + \
50 +                                ((n) > 3 ? (n)-3 : 0)*sizeof(short))
51 + #define freeface(f)     free((MEM_PTR)f)
52 +
53   #define TABSTOP         8       /* assumed number of characters per tab */
54   #define SHIFTW          2       /* nesting shift width */
55   #define MAXIND          15      /* maximum indent level */
56  
57 < extern int      i_comment(), i_object(), i_xf(), i_include(),
30 <                i_cyl(), i_face(), i_sph();
57 > char    tabs[MAXIND*SHIFTW+1];  /* current tab-in string */
58  
59 < int     vrmlout = 0;            /* VRML output desired? */
59 > #define curmatname      (c_cmname == NULL ? "mat" : to_id(c_cmname))
60  
61 < int     instancing = 0;         /* are we in an instance? */
61 > int     outtype = O_INV2;       /* output format */
62  
63 < char    tabs[MAXIND*SHIFTW+1];  /* current tab-in string */
63 > extern int      i_comment(), i_object(), i_xf(),
64 >                i_cyl(), i_face(), i_sph();
65  
66 + extern char     *to_id();
67  
68 +
69   main(argc, argv)
70   int     argc;
71   char    *argv[];
# Line 63 | Line 93 | char   *argv[];
93          mg_ehand[MG_E_TS] = c_hmaterial;        /* they get specular trans. */
94          mg_ehand[MG_E_VERTEX] = c_hvertex;      /* they get vertices */
95          mg_ehand[MG_E_XF] = i_xf;               /* we track transforms */
66        mg_ehand[MG_E_INCLUDE] = i_include;     /* we include files */
96          mg_init();              /* initialize the parser */
97 <        i = 1;                  /* get options and print format line */
98 <        if (i < argc && !strncmp(argv[i], "-vrml", strlen(argv[i]))) {
99 <                printf("#VRML 1.0 ascii\n");
100 <                vrmlout++;
101 <                i++;
102 <        } else
97 >                                /* get options and print format line */
98 >        for (i = 1; i < argc && argv[i][0] == '-'; i++)
99 >                if (!strcmp(argv[i], "-vrml"))
100 >                        outtype = O_VRML;
101 >                else if (!strcmp(argv[i], "-1"))
102 >                        outtype = O_INV1;
103 >                else if (!strcmp(argv[i], "-2"))
104 >                        outtype = O_INV2;
105 >                else
106 >                        goto userr;
107 >        switch (outtype) {
108 >        case O_INV1:
109 >                printf("#Inventor V1.0 ascii\n");
110 >                break;
111 >        case O_INV2:
112                  printf("#Inventor V2.0 ascii\n");
113 +                break;
114 +        case O_VRML:
115 +                printf("#VRML 1.0 ascii\n");
116 +                break;
117 +        }
118          printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
119          printf("Separator {\n");                /* begin root node */
120                                                  /* general properties */
121          printf("MaterialBinding { value OVERALL }\n");
122 <        printf("NormalBinding { value PER_VERTEX }\n");
123 <        printf("ShapeHints {\n");
124 <        printf("\tvertexOrdering CLOCKWISE\n");
125 <        printf("\tfaceType UNKNOWN_FACE_TYPE\n");
126 <        printf("}\n");
122 >        printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
123 >        if (outtype != O_INV1) {
124 >                printf("ShapeHints {\n");
125 >                printf("\tvertexOrdering CLOCKWISE\n");
126 >                printf("\tfaceType UNKNOWN_FACE_TYPE\n");
127 >                printf("}\n");
128 >        }
129          if (i == argc) {        /* load standard input */
130                  if (mg_load(NULL) != MG_OK)
131                          exit(1);
# Line 99 | Line 144 | char   *argv[];
144                          printf("## %s %s: %u unknown entities\n",
145                                          argv[0], argv[i], mg_nunknown);
146          }
147 <        printf("}\n");                          /* close root node */
147 >        flush_cache();          /* flush face cache, just in case */
148 >        printf("}\n");          /* close root node */
149          exit(0);
150 + userr:
151 +        fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
152 +        exit(1);
153   }
154  
155  
# Line 129 | Line 178 | i_comment(ac, av)                      /* transfer comment as is */
178   int     ac;
179   char    **av;
180   {
132        if (instancing)
133                return(MG_OK);
181          fputs(tabs, stdout);
182          putchar('#');                   /* Inventor comment character */
183          while (--ac > 0) {
# Line 149 | Line 196 | char   **av;
196   {
197          static int      objnest;
198  
199 <        if (instancing)
153 <                return(MG_OK);
199 >        flush_cache();                  /* flush cached objects */
200          if (ac == 2) {                          /* start group */
201 <                printf("%sDEF %s Group {\n", tabs, av[1]);
201 >                printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
202                  indent(1);
203                  objnest++;
204                  return(MG_OK);
# Line 177 | Line 223 | char   **av;
223          static long     xfid;
224          register XF_SPEC        *spec;
225  
226 <        if (instancing)
181 <                return(MG_OK);
226 >        flush_cache();                  /* flush cached objects */
227          if (ac == 1) {                  /* end of transform */
228                  if ((spec = xf_context) == NULL)
229                          return(MG_ECNTXT);
# Line 270 | Line 315 | register XF_SPEC       *spec;
315  
316  
317   int
273 i_include(ac, av)               /* include an MGF file */
274 int     ac;
275 char    **av;
276 {
277        static LUTAB    in_tab = LU_SINIT(free,free);   /* instance table */
278        static long     nincl;
279        LUENT   *lp;
280        char    *xfarg[MG_MAXARGC];
281        MG_FCTXT        ictx;
282        register int    i;
283
284        if (ac < 2)
285                return(MG_EARGC);
286        if (ac > 2) {                           /* start transform if one */
287                xfarg[0] = mg_ename[MG_E_XF];
288                for (i = 1; i < ac-1; i++)
289                        xfarg[i] = av[i+1];
290                xfarg[ac-1] = NULL;
291                if ((i = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK)
292                        return(i);
293        }
294                                                /* open include file */
295        if ((i = mg_open(&ictx, av[1])) != MG_OK)
296                return(i);
297                                                /* check for instance */
298        lp = lu_find(&in_tab, ictx.fname);
299        if (lp == NULL) goto memerr;
300        if (lp->data != NULL) {                 /* reference original */
301                instancing++;
302                printf("%sUSE %s\n", tabs, lp->data);
303                lp = NULL;
304        } else {                                /* else new original */
305                lp->key = (char *)malloc(strlen(ictx.fname)+1);
306                if (lp->key == NULL) goto memerr;
307                (void)strcpy(lp->key, ictx.fname);
308                if (ac > 2) {                   /* use transform group */
309                        lp->data = (char *)malloc(16);
310                        if (lp->data == NULL) goto memerr;
311                        sprintf(lp->data, "_xf%ld", xf_context->xid);
312                } else {                        /* else make our own group */
313                        lp->data = (char *)malloc(strlen(av[1])+16);
314                        if (lp->data == NULL) goto memerr;
315                        sprintf(lp->data, "_%s%ld", av[1], ++nincl);
316                        printf("%sDEF %s Group {\n", tabs, lp->data);
317                        indent(1);
318                }
319        }
320        while ((i = mg_read()) > 0) {           /* load include file */
321                if (i >= MG_MAXLINE-1) {
322                        fprintf(stderr, "%s: %d: %s\n", ictx.fname,
323                                        ictx.lineno, mg_err[MG_ELINE]);
324                        mg_close();
325                        return(MG_EINCL);
326                }
327                if ((i = mg_parse()) != MG_OK) {
328                        fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname,
329                                        ictx.lineno, mg_err[i],
330                                        ictx.inpline);
331                        mg_close();
332                        return(MG_EINCL);
333                }
334        }
335        if (lp == NULL)                         /* end instance? */
336                instancing--;
337        else if (ac <= 2) {                     /* else end group? */
338                indent(0);
339                printf("%s}\n", tabs);
340        }
341        mg_close();                             /* close and end transform */
342        if (ac > 2 && (i = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK)
343                return(i);
344        return(MG_OK);
345 memerr:
346        mg_close();
347        return(MG_EMEM);
348 }
349
350
351 int
318   put_material()                  /* put out current material */
319   {
320 <        char    *mname = "mat";
320 >        char    *mname = curmatname;
321          float   rgbval[3];
322  
357        if (c_cmname != NULL)
358                mname = c_cmname;
323          if (!c_cmaterial->clock) {      /* current, just use it */
324                  printf("%sUSE %s\n", tabs, mname);
325                  return(0);
# Line 366 | Line 330 | put_material()                 /* put out current material */
330          printf("%sMaterial {\n", tabs);
331          indent(1);
332          mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
333 <        printf("%sambientcolor %.4f %.4f %.4f\n", tabs,
333 >        printf("%sambientColor %.4f %.4f %.4f\n", tabs,
334                          rgbval[0], rgbval[1], rgbval[2]);
335 <        printf("%sdiffusecolor %.4f %.4f %.4f\n", tabs,
335 >        printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
336                          rgbval[0], rgbval[1], rgbval[2]);
337          if (c_cmaterial->rs > FTINY) {
338                  mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
339 <                printf("%sspecularcolor %.4f %.4f %.4f\n", tabs,
339 >                printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
340                                  rgbval[0], rgbval[1], rgbval[2]);
341 <                printf("%sshininess %.3f\n", tabs, 1.-c_cmaterial->rs_a);
341 >                printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
342          }
343          if (c_cmaterial->ed > FTINY) {
344                  mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
# Line 386 | Line 350 | put_material()                 /* put out current material */
350                                  c_cmaterial->ts + c_cmaterial->td);
351          indent(0);
352          printf("%s}\n", tabs);
353 <        printf("%sShapeHints { shapeType %s }\n", tabs,
353 >        if (outtype != O_INV1)
354 >                printf("%sShapeHints { shapeType %s }\n", tabs,
355                          c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
356          indent(0);
357          printf("%s}\n", tabs);
# Line 400 | Line 365 | i_face(ac, av)                 /* translate an N-sided face */
365   int     ac;
366   char    **av;
367   {
368 <        C_VERTEX        *vl[MG_MAXARGC-1];
369 <        int     donorms = 1;
368 >        static char     lastmat[MAXID];
369 >        struct face     *newf;
370 >        register C_VERTEX       *vp;
371 >        register LUENT  *lp;
372          register int    i;
373  
407        if (instancing)
408                return(MG_OK);
374          if (ac < 4)
375                  return(MG_EARGC);
376 <        printf("%sSeparator {\n", tabs);
377 <        indent(1);
378 <                                /* put out current material */
379 <        if (put_material() < 0)
380 <                return(MG_EBADMAT);
376 >        if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
377 >                        nverts == 0 || nverts+ac-1 >= MAXVERT) {
378 >                flush_cache();                  /* new cache */
379 >                lu_init(&vert_tab, MAXVERT);
380 >                printf("%sSeparator {\n", tabs);
381 >                indent(1);
382 >                if (put_material() < 0)         /* put out material */
383 >                        return(MG_EBADMAT);
384 >                (void)strcpy(lastmat, curmatname);
385 >        }
386 >                                /* allocate new face */
387 >        if ((newf = newface(ac-1)) == NULL)
388 >                return(MG_EMEM);
389 >        newf->nv = ac-1;
390                                  /* get vertex references */
391 <        for (i = 0; i < ac-1; i++) {
392 <                if ((vl[i] = c_getvert(av[i+1])) == NULL)
391 >        for (i = 0; i < newf->nv; i++) {
392 >                if ((vp = c_getvert(av[i+1])) == NULL)
393                          return(MG_EUNDEF);
394 <                if (is0vect(vl[i]->n))
395 <                        donorms = 0;
394 >                setvkey(vlist[nverts], vp);
395 >                lp = lu_find(&vert_tab, vlist[nverts]);
396 >                if (lp == NULL)
397 >                        return(MG_EMEM);
398 >                if (lp->key == NULL)
399 >                        lp->key = (char *)vlist[nverts++];
400 >                newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
401          }
402 <                                /* put out vertex coordinates */
403 <        printf("%sCoordinate3 {\n", tabs);
404 <        indent(1);
405 <        printf("%spoint [ %13.9g %13.9g %13.9g", tabs,
406 <                        vl[0]->p[0], vl[0]->p[1], vl[0]->p[2]);
407 <        for (i = 1; i < ac-1; i++)
408 <                printf(",\n%s        %13.9g %13.9g %13.9g", tabs,
409 <                        vl[i]->p[0], vl[i]->p[1], vl[i]->p[2]);
431 <        indent(0);
432 <        printf(" ]\n%s}\n", tabs);
433 <                                /* put out normal coordinates */
434 <        if (donorms) {
435 <                printf("%sNormal {\n", tabs);
436 <                indent(1);
437 <                printf("%svector [ %13.9g %13.9g %13.9g", tabs,
438 <                        vl[0]->n[0], vl[0]->p[1], vl[0]->p[2]);
439 <                for (i = 1; i < ac-1; i++)
440 <                        printf(",\n%s         %13.9g %13.9g %13.9g", tabs,
441 <                                        vl[i]->n[0], vl[i]->n[1], vl[i]->n[2]);
442 <                indent(0);
443 <                printf(" ]\n%s}\n", tabs);
444 <        } else
445 <                printf("%sNormal { }\n", tabs);
446 <                                /* put out actual face */
447 <        printf("%sIndexedFaceSet {\n", tabs);
448 <        indent(1);
449 <        printf("%scoordIndex [", tabs);
450 <        for (i = 0; i < ac-1; i++)
451 <                printf(" %d", i);
452 <        printf(" ]\n");
453 <        indent(0);
454 <        printf("%s}\n", tabs);
455 <        indent(0);
456 <        printf("%s}\n", tabs);
457 <        return(MG_OK);
402 >                                /* add to face list */
403 >        newf->next = NULL;
404 >        if (flist == NULL)
405 >                flist = newf;
406 >        else
407 >                flast->next = newf;
408 >        flast = newf;
409 >        return(MG_OK);          /* we'll actually put it out later */
410   }
411  
412  
# Line 465 | Line 417 | char   **av;
417   {
418          register C_VERTEX       *cent;
419  
468        if (instancing)
469                return(MG_OK);
420          if (ac != 3)
421                  return(MG_EARGC);
422 +        flush_cache();          /* flush vertex cache */
423          printf("%sSeparator {\n", tabs);
424          indent(1);
425                                  /* put out current material */
# Line 498 | Line 449 | char   **av;
449          FVECT   va;
450          double  length, angle;
451  
501        if (instancing)
502                return(MG_OK);
452          if (ac != 4)
453                  return(MG_EARGC);
454 +        flush_cache();          /* flush vertex cache */
455          printf("%sSeparator {\n", tabs);
456          indent(1);
457                                  /* put out current material */
# Line 518 | Line 468 | char   **av;
468          va[1] = v2->p[1] - v1->p[1];
469          va[2] = v2->p[2] - v1->p[2];
470          length = sqrt(DOT(va,va));
471 <        angle = 180./PI * acos(va[1]/length);
472 <        printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
473 <                        va[2], 0., -va[0], angle);
471 >        if (va[1] >= length)
472 >                angle = 0.;
473 >        else if (va[1] <= -length)
474 >                angle = PI;
475 >        else
476 >                angle = acos(va[1]/length);
477          printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
478                          .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
479                          .5*(v1->p[2]+v2->p[2]));
480 +        printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
481 +                        va[2], 0., -va[0], angle);
482                                  /* open-ended */
483          printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
484                          length, av[2]);
485          indent(0);
486          printf("%s}\n", tabs);
487          return(MG_OK);
488 + }
489 +
490 +
491 + char *
492 + to_id(name)                     /* make sure a name is a valid Inventor ID */
493 + register char   *name;
494 + {
495 +        static char     id[MAXID];
496 +        register char   *cp;
497 +
498 +        for (cp = id; *name && cp < MAXID-1+id; name++)
499 +                if (isalnum(*name) || *name == '_')
500 +                        *cp++ = *name;
501 +                else
502 +                        *cp++ = '_';
503 +        *cp = '\0';
504 +        return(id);
505 + }
506 +
507 +
508 + flush_cache()                   /* put out cached faces */
509 + {
510 +        int     donorms = 0;
511 +        register struct face    *f;
512 +        register int    i;
513 +
514 +        if (nverts == 0)
515 +                return;
516 +                                        /* put out coordinates */
517 +        printf("%sCoordinate3 {\n", tabs);
518 +        indent(1);
519 +        vlist[0][VFSEPPOS] = '\0';
520 +        printf("%spoint [ %s", tabs, vlist[0]);
521 +        for (i = 1; i < nverts; i++) {
522 +                vlist[i][VFSEPPOS] = '\0';
523 +                printf(",\n%s        %s", tabs, vlist[i]);
524 +                if (strcmp(VFSEPPOS+1+vlist[i], VZVECT))
525 +                        donorms++;
526 +        }
527 +        indent(0);
528 +        printf(" ]\n%s}\n", tabs);
529 +        if (donorms) {                  /* put out normals */
530 +                printf("%sNormal {\n", tabs);
531 +                indent(1);
532 +                printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]);
533 +                for (i = 1; i < nverts; i++)
534 +                        printf(",\n%s         %s", tabs, VFSEPPOS+1+vlist[i]);
535 +                indent(0);
536 +                printf(" ]\n%s}\n", tabs);
537 +        }
538 +                                        /* put out faces */
539 +        printf("%sIndexedFaceSet {\n", tabs);
540 +        indent(1);
541 +        f = flist;                      /* coordinate indices */
542 +        printf("%scoordIndex [ %d", tabs, f->vl[0]);
543 +        for (i = 1; i < f->nv; i++)
544 +                printf(", %d", f->vl[i]);
545 +        for (f = f->next; f != NULL; f = f->next) {
546 +                printf(", -1,\n%s             %d", tabs, f->vl[0]);
547 +                for (i = 1; i < f->nv; i++)
548 +                        printf(", %d", f->vl[i]);
549 +        }
550 +        printf(" ]\n");
551 +        if (donorms) {
552 +                f = flist;                      /* normal indices */
553 +                printf("%snormalIndex [ %d", tabs, f->vl[0]);
554 +                for (i = 1; i < f->nv; i++)
555 +                        printf(", %d", f->vl[i]);
556 +                for (f = f->next; f != NULL; f = f->next) {
557 +                        printf(", -1,\n%s              %d", tabs, f->vl[0]);
558 +                        for (i = 1; i < f->nv; i++)
559 +                                printf(", %d", f->vl[i]);
560 +                }
561 +                printf(" ]\n");
562 +        }
563 +        indent(0);                      /* close IndexedFaceSet */
564 +        printf("%s}\n", tabs);
565 +        indent(0);                      /* close face group */
566 +        printf("%s}\n", tabs);
567 +        while ((f = flist) != NULL) {   /* free face list */
568 +                flist = f->next;
569 +                freeface(f);
570 +        }
571 +        lu_done(&vert_tab);             /* clear lookup table */
572 +        nverts = 0;
573   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines