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.11 by schorsch, Sat Nov 15 17:54:06 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1995 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Convert MGF to Inventor file.
6   *
# Line 12 | Line 9 | static char SCCSid[] = "$SunId$ LBL";
9  
10   #include <stdio.h>
11  
12 + #include <stdlib.h>
13 +
14   #include <math.h>
15  
16 + #include <ctype.h>
17 +
18 + #include <string.h>
19 +
20   #include "parser.h"
21  
22   #include "lookup.h"
23  
24 < #ifndef PI
25 < #define PI              3.14159265358979323846
26 < #endif
24 > #define O_INV1          1       /* Inventor 1.0 output */
25 > #define O_INV2          2       /* Inventor 2.0 output */
26 > #define O_VRML1         3       /* VRML 1.0 output */
27  
28 + #define MAXID           48      /* maximum identifier length */
29 +
30 + #define VERTFMT         "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f"
31 + #define VZVECT          "+0.000 +0.000 +0.000"
32 + #define VFSEPPOS        50      /* position of newline in above */
33 + #define VFLEN           72      /* total vertex string length */
34 + #define MAXVERT         10240   /* maximum cached vertices */
35 +
36 + #define setvkey(k,v)    sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\
37 +                                        (v)->n[0],(v)->n[1],(v)->n[2]);
38 +
39 + char    vlist[MAXVERT][VFLEN];  /* our vertex cache */
40 + int     nverts;                 /* current cache size */
41 +
42 + LUTAB   vert_tab = LU_SINIT(NULL,NULL);
43 +
44 + struct face {
45 +        struct face     *next;          /* next face in list */
46 +        short           nv;             /* number of vertices */
47 +        short           vl[3];          /* vertex index list (variable) */
48 + }       *flist, *flast;         /* our face cache */
49 +
50 + #define newface(n)      (struct face *)malloc(sizeof(struct face) + \
51 +                                ((n) > 3 ? (n)-3 : 0)*sizeof(short))
52 + #define freeface(f)     free((MEM_PTR)f)
53 +
54   #define TABSTOP         8       /* assumed number of characters per tab */
55   #define SHIFTW          2       /* nesting shift width */
56   #define MAXIND          15      /* maximum indent level */
57  
58 < extern int      i_comment(), i_object(), i_xf(), i_include(),
30 <                i_cyl(), i_face(), i_sph();
58 > char    tabs[MAXIND*SHIFTW+1];  /* current tab-in string */
59  
60 < int     vrmlout = 0;            /* VRML output desired? */
60 > #define curmatname      (c_cmname == NULL ? "mat" : to_id(c_cmname))
61  
62 < int     instancing = 0;         /* are we in an instance? */
62 > int     outtype = O_INV2;       /* output format */
63  
64 < char    tabs[MAXIND*SHIFTW+1];  /* current tab-in string */
64 > int i_comment(int ac, char **av);
65 > int i_object(int ac, char **av);
66 > int i_xf(int ac, char **av);
67 > int put_xform(register XF_SPEC *spec);
68 > int put_material(void);
69 > int i_face(int ac, char **av);
70 > int i_sph(int ac, char **av);
71 > int i_cyl(int ac, char **av);
72 > char * to_id(register char *name);
73 > char * to_id(register char *name);
74 > void flush_cache(void);
75  
76  
77 < main(argc, argv)
78 < int     argc;
79 < char    *argv[];
77 > int
78 > main(
79 >        int     argc,
80 >        char    *argv[]
81 > )
82   {
83          int     i;
84                                  /* initialize dispatch table */
# Line 63 | Line 103 | char   *argv[];
103          mg_ehand[MG_E_TS] = c_hmaterial;        /* they get specular trans. */
104          mg_ehand[MG_E_VERTEX] = c_hvertex;      /* they get vertices */
105          mg_ehand[MG_E_XF] = i_xf;               /* we track transforms */
66        mg_ehand[MG_E_INCLUDE] = i_include;     /* we include files */
106          mg_init();              /* initialize the parser */
107 <        i = 1;                  /* get options and print format line */
108 <        if (i < argc && !strncmp(argv[i], "-vrml", strlen(argv[i]))) {
109 <                printf("#VRML 1.0 ascii\n");
110 <                vrmlout++;
111 <                i++;
112 <        } else
107 >                                /* get options and print format line */
108 >        for (i = 1; i < argc && argv[i][0] == '-'; i++)
109 >                if (!strcmp(argv[i], "-vrml"))
110 >                        outtype = O_VRML1;
111 >                else if (!strcmp(argv[i], "-1"))
112 >                        outtype = O_INV1;
113 >                else if (!strcmp(argv[i], "-2"))
114 >                        outtype = O_INV2;
115 >                else
116 >                        goto userr;
117 >        switch (outtype) {
118 >        case O_INV1:
119 >                printf("#Inventor V1.0 ascii\n");
120 >                break;
121 >        case O_INV2:
122                  printf("#Inventor V2.0 ascii\n");
123 +                break;
124 +        case O_VRML1:
125 +                printf("#VRML V1.0 ascii\n");
126 +                break;
127 +        }
128          printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
129          printf("Separator {\n");                /* begin root node */
130                                                  /* general properties */
131          printf("MaterialBinding { value OVERALL }\n");
132 <        printf("NormalBinding { value PER_VERTEX }\n");
133 <        printf("ShapeHints {\n");
134 <        printf("\tvertexOrdering CLOCKWISE\n");
135 <        printf("\tfaceType UNKNOWN_FACE_TYPE\n");
136 <        printf("}\n");
132 >        printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
133 >        if (outtype != O_INV1) {
134 >                printf("ShapeHints {\n");
135 >                printf("\tvertexOrdering CLOCKWISE\n");
136 >                printf("\tfaceType UNKNOWN_FACE_TYPE\n");
137 >                printf("}\n");
138 >        }
139          if (i == argc) {        /* load standard input */
140                  if (mg_load(NULL) != MG_OK)
141                          exit(1);
# Line 99 | Line 154 | char   *argv[];
154                          printf("## %s %s: %u unknown entities\n",
155                                          argv[0], argv[i], mg_nunknown);
156          }
157 <        printf("}\n");                          /* close root node */
157 >        flush_cache();          /* flush face cache, just in case */
158 >        printf("}\n");          /* close root node */
159          exit(0);
160 + userr:
161 +        fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
162 +        exit(1);
163   }
164  
165  
166 < indent(deeper)                          /* indent in or out */
167 < int     deeper;
166 > void
167 > indent(                         /* indent in or out */
168 >        int     deeper
169 > )
170   {
171          static int      level;          /* current nesting level */
172          register int    i;
# Line 125 | Line 186 | int    deeper;
186  
187  
188   int
189 < i_comment(ac, av)                       /* transfer comment as is */
190 < int     ac;
191 < char    **av;
189 > i_comment(                      /* transfer comment as is */
190 >        int     ac,
191 >        char    **av
192 > )
193   {
132        if (instancing)
133                return(MG_OK);
194          fputs(tabs, stdout);
195          putchar('#');                   /* Inventor comment character */
196          while (--ac > 0) {
# Line 143 | Line 203 | char   **av;
203  
204  
205   int
206 < i_object(ac, av)                        /* group object name */
207 < int     ac;
208 < char    **av;
206 > i_object(                       /* group object name */
207 >        int     ac,
208 >        char    **av
209 > )
210   {
211          static int      objnest;
212  
213 <        if (instancing)
153 <                return(MG_OK);
213 >        flush_cache();                  /* flush cached objects */
214          if (ac == 2) {                          /* start group */
215 <                printf("%sDEF %s Group {\n", tabs, av[1]);
215 >                printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
216                  indent(1);
217                  objnest++;
218                  return(MG_OK);
# Line 170 | Line 230 | char   **av;
230  
231  
232   int
233 < i_xf(ac, av)                            /* transform object(s) */
234 < int     ac;
235 < char    **av;
233 > i_xf(                           /* transform object(s) */
234 >        int     ac,
235 >        char    **av
236 > )
237   {
238          static long     xfid;
239          register XF_SPEC        *spec;
240  
241 <        if (instancing)
181 <                return(MG_OK);
241 >        flush_cache();                  /* flush cached objects */
242          if (ac == 1) {                  /* end of transform */
243                  if ((spec = xf_context) == NULL)
244                          return(MG_ECNTXT);
# Line 239 | Line 299 | char   **av;
299  
300  
301   int
302 < put_xform(spec)                 /* translate and print transform */
303 < register XF_SPEC        *spec;
302 > put_xform(                      /* translate and print transform */
303 >        register XF_SPEC        *spec
304 > )
305   {
306          register char   **av;
307          register int    n;
# Line 270 | Line 331 | register XF_SPEC       *spec;
331  
332  
333   int
334 < i_include(ac, av)               /* include an MGF file */
274 < int     ac;
275 < char    **av;
334 > put_material(void)                      /* put out current material */
335   {
336 <        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
352 < put_material()                  /* put out current material */
353 < {
354 <        char    *mname = "mat";
336 >        char    *mname = curmatname;
337          float   rgbval[3];
338  
357        if (c_cmname != NULL)
358                mname = c_cmname;
339          if (!c_cmaterial->clock) {      /* current, just use it */
340                  printf("%sUSE %s\n", tabs, mname);
341                  return(0);
# Line 366 | Line 346 | put_material()                 /* put out current material */
346          printf("%sMaterial {\n", tabs);
347          indent(1);
348          mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
349 <        printf("%sambientcolor %.4f %.4f %.4f\n", tabs,
349 >        printf("%sambientColor %.4f %.4f %.4f\n", tabs,
350                          rgbval[0], rgbval[1], rgbval[2]);
351 <        printf("%sdiffusecolor %.4f %.4f %.4f\n", tabs,
351 >        printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
352                          rgbval[0], rgbval[1], rgbval[2]);
353          if (c_cmaterial->rs > FTINY) {
354                  mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
355 <                printf("%sspecularcolor %.4f %.4f %.4f\n", tabs,
355 >                printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
356                                  rgbval[0], rgbval[1], rgbval[2]);
357 <                printf("%sshininess %.3f\n", tabs, 1.-c_cmaterial->rs_a);
357 >                printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
358          }
359          if (c_cmaterial->ed > FTINY) {
360                  mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
# Line 386 | Line 366 | put_material()                 /* put out current material */
366                                  c_cmaterial->ts + c_cmaterial->td);
367          indent(0);
368          printf("%s}\n", tabs);
369 <        printf("%sShapeHints { shapeType %s }\n", tabs,
369 >        if (outtype != O_INV1)
370 >                printf("%sShapeHints { shapeType %s faceType UNKNOWN_FACE_TYPE }\n",
371 >                        tabs,
372                          c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
373          indent(0);
374          printf("%s}\n", tabs);
# Line 396 | Line 378 | put_material()                 /* put out current material */
378  
379  
380   int
381 < i_face(ac, av)                  /* translate an N-sided face */
382 < int     ac;
383 < char    **av;
381 > i_face(                 /* translate an N-sided face */
382 >        int     ac,
383 >        char    **av
384 > )
385   {
386 <        C_VERTEX        *vl[MG_MAXARGC-1];
387 <        int     donorms = 1;
386 >        static char     lastmat[MAXID];
387 >        struct face     *newf;
388 >        register C_VERTEX       *vp;
389 >        register LUENT  *lp;
390          register int    i;
391  
407        if (instancing)
408                return(MG_OK);
392          if (ac < 4)
393                  return(MG_EARGC);
394 <        printf("%sSeparator {\n", tabs);
395 <        indent(1);
396 <                                /* put out current material */
397 <        if (put_material() < 0)
398 <                return(MG_EBADMAT);
394 >        if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
395 >                        nverts == 0 || nverts+ac-1 >= MAXVERT) {
396 >                flush_cache();                  /* new cache */
397 >                lu_init(&vert_tab, MAXVERT);
398 >                printf("%sSeparator {\n", tabs);
399 >                indent(1);
400 >                if (put_material() < 0)         /* put out material */
401 >                        return(MG_EBADMAT);
402 >                (void)strcpy(lastmat, curmatname);
403 >        }
404 >                                /* allocate new face */
405 >        if ((newf = newface(ac-1)) == NULL)
406 >                return(MG_EMEM);
407 >        newf->nv = ac-1;
408                                  /* get vertex references */
409 <        for (i = 0; i < ac-1; i++) {
410 <                if ((vl[i] = c_getvert(av[i+1])) == NULL)
409 >        for (i = 0; i < newf->nv; i++) {
410 >                if ((vp = c_getvert(av[i+1])) == NULL)
411                          return(MG_EUNDEF);
412 <                if (is0vect(vl[i]->n))
413 <                        donorms = 0;
412 >                setvkey(vlist[nverts], vp);
413 >                lp = lu_find(&vert_tab, vlist[nverts]);
414 >                if (lp == NULL)
415 >                        return(MG_EMEM);
416 >                if (lp->key == NULL)
417 >                        lp->key = (char *)vlist[nverts++];
418 >                newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
419          }
420 <                                /* put out vertex coordinates */
421 <        printf("%sCoordinate3 {\n", tabs);
422 <        indent(1);
423 <        printf("%spoint [ %13.9g %13.9g %13.9g", tabs,
424 <                        vl[0]->p[0], vl[0]->p[1], vl[0]->p[2]);
425 <        for (i = 1; i < ac-1; i++)
426 <                printf(",\n%s        %13.9g %13.9g %13.9g", tabs,
427 <                        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);
420 >                                /* add to face list */
421 >        newf->next = NULL;
422 >        if (flist == NULL)
423 >                flist = newf;
424 >        else
425 >                flast->next = newf;
426 >        flast = newf;
427 >        return(MG_OK);          /* we'll actually put it out later */
428   }
429  
430  
431   int
432 < i_sph(ac, av)                   /* translate sphere description */
433 < int     ac;
434 < char    **av;
432 > i_sph(                  /* translate sphere description */
433 >        int     ac,
434 >        char    **av
435 > )
436   {
437          register C_VERTEX       *cent;
438  
468        if (instancing)
469                return(MG_OK);
439          if (ac != 3)
440                  return(MG_EARGC);
441 +        flush_cache();          /* flush vertex cache */
442          printf("%sSeparator {\n", tabs);
443          indent(1);
444                                  /* put out current material */
# Line 490 | Line 460 | char   **av;
460  
461  
462   int
463 < i_cyl(ac, av)                   /* translate a cylinder description */
464 < int     ac;
465 < char    **av;
463 > i_cyl(                  /* translate a cylinder description */
464 >        int     ac,
465 >        char    **av
466 > )
467   {
468          register C_VERTEX       *v1, *v2;
469          FVECT   va;
470          double  length, angle;
471  
501        if (instancing)
502                return(MG_OK);
472          if (ac != 4)
473                  return(MG_EARGC);
474 +        flush_cache();          /* flush vertex cache */
475          printf("%sSeparator {\n", tabs);
476          indent(1);
477                                  /* put out current material */
478          if (put_material() < 0)
479                  return(MG_EBADMAT);
480                                  /* get endpoints */
481 <        if ((v1 = c_getvert(av[1])) == NULL | (v2 = c_getvert(av[3])) == NULL)
481 >        if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
482                  return(MG_EUNDEF);
483                                  /* get radius */
484          if (!isflt(av[2]))
# Line 518 | Line 488 | char   **av;
488          va[1] = v2->p[1] - v1->p[1];
489          va[2] = v2->p[2] - v1->p[2];
490          length = sqrt(DOT(va,va));
491 <        angle = 180./PI * acos(va[1]/length);
492 <        printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
493 <                        va[2], 0., -va[0], angle);
491 >        if (va[1] >= length)
492 >                angle = 0.;
493 >        else if (va[1] <= -length)
494 >                angle = PI;
495 >        else
496 >                angle = acos(va[1]/length);
497          printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
498                          .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
499                          .5*(v1->p[2]+v2->p[2]));
500 +        printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
501 +                        va[2], 0., -va[0], angle);
502                                  /* open-ended */
503          printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
504                          length, av[2]);
505          indent(0);
506          printf("%s}\n", tabs);
507          return(MG_OK);
508 + }
509 +
510 +
511 + char *
512 + to_id(                  /* make sure a name is a valid Inventor ID */
513 +        register char   *name
514 + )
515 + {
516 +        static char     id[MAXID];
517 +        register char   *cp;
518 +
519 +        for (cp = id; *name && cp < MAXID-1+id; name++)
520 +                if (isalnum(*name) || *name == '_')
521 +                        *cp++ = *name;
522 +                else
523 +                        *cp++ = '_';
524 +        *cp = '\0';
525 +        return(id);
526 + }
527 +
528 +
529 + void
530 + flush_cache(void)                       /* put out cached faces */
531 + {
532 +        int     donorms = 0;
533 +        register struct face    *f;
534 +        register int    i;
535 +
536 +        if (nverts == 0)
537 +                return;
538 +                                        /* put out coordinates */
539 +        printf("%sCoordinate3 {\n", tabs);
540 +        indent(1);
541 +        vlist[0][VFSEPPOS] = '\0';
542 +        printf("%spoint [ %s", tabs, vlist[0]);
543 +        for (i = 1; i < nverts; i++) {
544 +                vlist[i][VFSEPPOS] = '\0';
545 +                printf(",\n%s        %s", tabs, vlist[i]);
546 +                if (strcmp(VFSEPPOS+1+vlist[i], VZVECT))
547 +                        donorms++;
548 +        }
549 +        indent(0);
550 +        printf(" ]\n%s}\n", tabs);
551 +        if (donorms) {                  /* put out normals */
552 +                printf("%sNormal {\n", tabs);
553 +                indent(1);
554 +                printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]);
555 +                for (i = 1; i < nverts; i++)
556 +                        printf(",\n%s         %s", tabs, VFSEPPOS+1+vlist[i]);
557 +                indent(0);
558 +                printf(" ]\n%s}\n", tabs);
559 +        }
560 +                                        /* put out faces */
561 +        printf("%sIndexedFaceSet {\n", tabs);
562 +        indent(1);
563 +        f = flist;                      /* coordinate indices */
564 +        printf("%scoordIndex [ %d", tabs, f->vl[0]);
565 +        for (i = 1; i < f->nv; i++)
566 +                printf(", %d", f->vl[i]);
567 +        for (f = f->next; f != NULL; f = f->next) {
568 +                printf(", -1,\n%s             %d", tabs, f->vl[0]);
569 +                for (i = 1; i < f->nv; i++)
570 +                        printf(", %d", f->vl[i]);
571 +        }
572 +        printf(" ]\n");
573 +        if (donorms) {
574 +                f = flist;                      /* normal indices */
575 +                printf("%snormalIndex [ %d", tabs, f->vl[0]);
576 +                for (i = 1; i < f->nv; i++)
577 +                        printf(", %d", f->vl[i]);
578 +                for (f = f->next; f != NULL; f = f->next) {
579 +                        printf(", -1,\n%s              %d", tabs, f->vl[0]);
580 +                        for (i = 1; i < f->nv; i++)
581 +                                printf(", %d", f->vl[i]);
582 +                }
583 +                printf(" ]\n");
584 +        }
585 +        indent(0);                      /* close IndexedFaceSet */
586 +        printf("%s}\n", tabs);
587 +        indent(0);                      /* close face group */
588 +        printf("%s}\n", tabs);
589 +        while ((f = flist) != NULL) {   /* free face list */
590 +                flist = f->next;
591 +                freeface(f);
592 +        }
593 +        lu_done(&vert_tab);             /* clear lookup table */
594 +        nverts = 0;
595   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines