Back to index

radiance  4R0+20100331
Classes | Defines | Functions | Variables
mgf2inv.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include "parser.h"
#include "lookup.h"

Go to the source code of this file.

Classes

struct  face

Defines

#define O_INV1   1 /* Inventor 1.0 output */
#define O_INV2   2 /* Inventor 2.0 output */
#define O_VRML1   3 /* VRML 1.0 output */
#define MAXID   48 /* maximum identifier length */
#define VERTFMT   "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f"
#define VZVECT   "+0.000 +0.000 +0.000"
#define VFSEPPOS   50 /* position of newline in above */
#define VFLEN   72 /* total vertex string length */
#define MAXVERT   10240 /* maximum cached vertices */
#define setvkey(k, v)
#define newface(n)
#define freeface(f)   free((MEM_PTR)f)
#define TABSTOP   8 /* assumed number of characters per tab */
#define SHIFTW   2 /* nesting shift width */
#define MAXIND   15 /* maximum indent level */
#define curmatname   (c_cmname == NULL ? "mat" : to_id(c_cmname))

Functions

int i_comment (int ac, char **av)
int i_object (int ac, char **av)
int i_xf (int ac, char **av)
int put_xform (register XF_SPEC *spec)
int put_material (void)
int i_face (int ac, char **av)
int i_sph (int ac, char **av)
int i_cyl (int ac, char **av)
char * to_id (register char *name)
void flush_cache (void)
int main (int argc, char *argv[])
void indent (int deeper)

Variables

static const char RCSid [] = "$Id: mgf2inv.c,v 1.11 2003/11/15 17:54:06 schorsch Exp $"
char vlist [MAXVERT][VFLEN]
int nverts
LUTAB vert_tab = LU_SINIT(NULL,NULL)
struct faceflist
struct faceflast
char tabs [MAXIND *SHIFTW+1]
int outtype = O_INV2

Class Documentation

struct face

Definition at line 44 of file mgf2inv.c.

Collaboration diagram for face:
Class Members
struct face * next
short nv
short vl

Define Documentation

#define curmatname   (c_cmname == NULL ? "mat" : to_id(c_cmname))

Definition at line 60 of file mgf2inv.c.

#define freeface (   f)    free((MEM_PTR)f)

Definition at line 52 of file mgf2inv.c.

#define MAXID   48 /* maximum identifier length */

Definition at line 28 of file mgf2inv.c.

#define MAXIND   15 /* maximum indent level */

Definition at line 56 of file mgf2inv.c.

#define MAXVERT   10240 /* maximum cached vertices */

Definition at line 34 of file mgf2inv.c.

#define newface (   n)
Value:
(struct face *)malloc(sizeof(struct face) + \
                            ((n) > 3 ? (n)-3 : 0)*sizeof(short))

Definition at line 50 of file mgf2inv.c.

#define O_INV1   1 /* Inventor 1.0 output */

Definition at line 24 of file mgf2inv.c.

#define O_INV2   2 /* Inventor 2.0 output */

Definition at line 25 of file mgf2inv.c.

#define O_VRML1   3 /* VRML 1.0 output */

Definition at line 26 of file mgf2inv.c.

#define setvkey (   k,
  v 
)
Value:
sprintf(k,VERTFMT,(v)->p[0],(v)->p[1],(v)->p[2],\
                                   (v)->n[0],(v)->n[1],(v)->n[2]);

Definition at line 36 of file mgf2inv.c.

#define SHIFTW   2 /* nesting shift width */

Definition at line 55 of file mgf2inv.c.

#define TABSTOP   8 /* assumed number of characters per tab */

Definition at line 54 of file mgf2inv.c.

#define VERTFMT   "%+16.9e %+16.9e %+16.9e\n%+6.3f %+6.3f %+6.3f"

Definition at line 30 of file mgf2inv.c.

#define VFLEN   72 /* total vertex string length */

Definition at line 33 of file mgf2inv.c.

#define VFSEPPOS   50 /* position of newline in above */

Definition at line 32 of file mgf2inv.c.

#define VZVECT   "+0.000 +0.000 +0.000"

Definition at line 31 of file mgf2inv.c.


Function Documentation

void flush_cache ( void  )

Definition at line 530 of file mgf2inv.c.

{
       int    donorms = 0;
       register struct face *f;
       register int  i;

       if (nverts == 0)
              return;
                                   /* put out coordinates */
       printf("%sCoordinate3 {\n", tabs);
       indent(1);
       vlist[0][VFSEPPOS] = '\0';
       printf("%spoint [ %s", tabs, vlist[0]);
       for (i = 1; i < nverts; i++) {
              vlist[i][VFSEPPOS] = '\0';
              printf(",\n%s        %s", tabs, vlist[i]);
              if (strcmp(VFSEPPOS+1+vlist[i], VZVECT))
                     donorms++;
       }
       indent(0);
       printf(" ]\n%s}\n", tabs);
       if (donorms) {                     /* put out normals */
              printf("%sNormal {\n", tabs);
              indent(1);
              printf("%svector [ %s", tabs, VFSEPPOS+1+vlist[0]);
              for (i = 1; i < nverts; i++)
                     printf(",\n%s         %s", tabs, VFSEPPOS+1+vlist[i]);
              indent(0);
              printf(" ]\n%s}\n", tabs);
       }
                                   /* put out faces */
       printf("%sIndexedFaceSet {\n", tabs);
       indent(1);
       f = flist;                  /* coordinate indices */
       printf("%scoordIndex [ %d", tabs, f->vl[0]);
       for (i = 1; i < f->nv; i++)
              printf(", %d", f->vl[i]);
       for (f = f->next; f != NULL; f = f->next) {
              printf(", -1,\n%s             %d", tabs, f->vl[0]);
              for (i = 1; i < f->nv; i++)
                     printf(", %d", f->vl[i]);
       }
       printf(" ]\n");
       if (donorms) {
              f = flist;                  /* normal indices */
              printf("%snormalIndex [ %d", tabs, f->vl[0]);
              for (i = 1; i < f->nv; i++)
                     printf(", %d", f->vl[i]);
              for (f = f->next; f != NULL; f = f->next) {
                     printf(", -1,\n%s              %d", tabs, f->vl[0]);
                     for (i = 1; i < f->nv; i++)
                            printf(", %d", f->vl[i]);
              }
              printf(" ]\n");
       }
       indent(0);                  /* close IndexedFaceSet */
       printf("%s}\n", tabs);
       indent(0);                  /* close face group */
       printf("%s}\n", tabs);
       while ((f = flist) != NULL) {      /* free face list */
              flist = f->next;
              freeface(f);
       }
       lu_done(&vert_tab);         /* clear lookup table */
       nverts = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int i_comment ( int  ac,
char **  av 
)

Definition at line 189 of file mgf2inv.c.

{
       fputs(tabs, stdout);
       putchar('#');               /* Inventor comment character */
       while (--ac > 0) {
              putchar(' ');
              fputs(*++av, stdout);
       }
       putchar('\n');
       return(MG_OK);
}

Here is the caller graph for this function:

int i_cyl ( int  ac,
char **  av 
)

Definition at line 463 of file mgf2inv.c.

{
       register C_VERTEX    *v1, *v2;
       FVECT  va;
       double length, angle;

       if (ac != 4)
              return(MG_EARGC);
       flush_cache();              /* flush vertex cache */
       printf("%sSeparator {\n", tabs);
       indent(1);
                            /* put out current material */
       if (put_material() < 0)
              return(MG_EBADMAT);
                            /* get endpoints */
       if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
              return(MG_EUNDEF);
                            /* get radius */
       if (!isflt(av[2]))
              return(MG_ETYPE);
                            /* compute transform */
       va[0] = v2->p[0] - v1->p[0];
       va[1] = v2->p[1] - v1->p[1];
       va[2] = v2->p[2] - v1->p[2];
       length = sqrt(DOT(va,va));
       if (va[1] >= length)
              angle = 0.;
       else if (va[1] <= -length)
              angle = PI;
       else
              angle = acos(va[1]/length);
       printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
                     .5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
                     .5*(v1->p[2]+v2->p[2]));
       printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
                     va[2], 0., -va[0], angle);
                            /* open-ended */
       printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
                     length, av[2]);
       indent(0);
       printf("%s}\n", tabs);
       return(MG_OK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int i_face ( int  ac,
char **  av 
)

Definition at line 381 of file mgf2inv.c.

{
       static char   lastmat[MAXID];
       struct face   *newf;
       register C_VERTEX    *vp;
       register LUENT       *lp;
       register int  i;

       if (ac < 4)
              return(MG_EARGC);
       if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
                     nverts == 0 || nverts+ac-1 >= MAXVERT) {
              flush_cache();                     /* new cache */
              lu_init(&vert_tab, MAXVERT);
              printf("%sSeparator {\n", tabs);
              indent(1);
              if (put_material() < 0)            /* put out material */
                     return(MG_EBADMAT);
              (void)strcpy(lastmat, curmatname);
       }
                            /* allocate new face */
       if ((newf = newface(ac-1)) == NULL)
              return(MG_EMEM);
       newf->nv = ac-1;
                            /* get vertex references */
       for (i = 0; i < newf->nv; i++) {
              if ((vp = c_getvert(av[i+1])) == NULL)
                     return(MG_EUNDEF);
              setvkey(vlist[nverts], vp);
              lp = lu_find(&vert_tab, vlist[nverts]);
              if (lp == NULL)
                     return(MG_EMEM);
              if (lp->key == NULL)
                     lp->key = (char *)vlist[nverts++];
              newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
       }
                            /* add to face list */
       newf->next = NULL;
       if (flist == NULL)
              flist = newf;
       else
              flast->next = newf;
       flast = newf;
       return(MG_OK);              /* we'll actually put it out later */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int i_object ( int  ac,
char **  av 
)

Definition at line 206 of file mgf2inv.c.

{
       static int    objnest;

       flush_cache();                     /* flush cached objects */
       if (ac == 2) {                            /* start group */
              printf("%sDEF %s Group {\n", tabs, to_id(av[1]));
              indent(1);
              objnest++;
              return(MG_OK);
       }
       if (ac == 1) {                            /* end group */
              if (--objnest < 0)
                     return(MG_ECNTXT);
              indent(0);
              fputs(tabs, stdout);
              fputs("}\n", stdout);
              return(MG_OK);
       }
       return(MG_EARGC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int i_sph ( int  ac,
char **  av 
)

Definition at line 432 of file mgf2inv.c.

{
       register C_VERTEX    *cent;

       if (ac != 3)
              return(MG_EARGC);
       flush_cache();              /* flush vertex cache */
       printf("%sSeparator {\n", tabs);
       indent(1);
                            /* put out current material */
       if (put_material() < 0)
              return(MG_EBADMAT);
                            /* get center */
       if ((cent = c_getvert(av[1])) == NULL)
              return(MG_EUNDEF);
                            /* get radius */
       if (!isflt(av[2]))
              return(MG_ETYPE);
       printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
                     cent->p[0], cent->p[1], cent->p[2]);
       printf("%sSphere { radius %s }\n", tabs, av[2]);
       indent(0);
       printf("%s}\n", tabs);
       return(MG_OK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int i_xf ( int  ac,
char **  av 
)

Definition at line 233 of file mgf2inv.c.

{
       static long   xfid;
       register XF_SPEC     *spec;

       flush_cache();                     /* flush cached objects */
       if (ac == 1) {                     /* end of transform */
              if ((spec = xf_context) == NULL)
                     return(MG_ECNTXT);
              indent(0);                  /* close original segment */
              printf("%s}\n", tabs);
              indent(0);
              printf("%s}\n", tabs);
              if (spec->xarr != NULL) {   /* check for iteration */
                     register struct xf_array    *ap = spec->xarr;
                     register int  n;

                     ap->aarg[ap->ndim-1].i = 1; /* iterate array */
                     for ( ; ; ) {
                            n = ap->ndim-1;
                            while (ap->aarg[n].i < ap->aarg[n].n) {
                                   sprintf(ap->aarg[n].arg, "%d",
                                                 ap->aarg[n].i);
                                   printf("%sSeparator {\n", tabs);
                                   indent(1);
                                   (void)put_xform(spec);
                                   printf("%sUSE _xf%ld\n", tabs,
                                                 spec->xid);
                                   indent(0);
                                   printf("%s}\n", tabs);
                                   ++ap->aarg[n].i;
                            }
                            ap->aarg[n].i = 0;
                            (void)strcpy(ap->aarg[n].arg, "0");
                            while (n-- && ++ap->aarg[n].i >= ap->aarg[n].n) {
                                   ap->aarg[n].i = 0;
                                   (void)strcpy(ap->aarg[n].arg, "0");
                            }
                            if (n < 0)
                                   break;
                            sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
                     }
              }
                                          /* pop transform */
              xf_context = spec->prev;
              free_xf(spec);
              return(MG_OK);
       }
                                   /* else allocate new transform */
       if ((spec = new_xf(ac-1, av+1)) == NULL)
              return(MG_EMEM);
       spec->xid = ++xfid;         /* assign unique ID */
       spec->prev = xf_context;    /* push onto stack */
       xf_context = spec;
                                   /* translate xf specification */
       printf("%sSeparator {\n", tabs);
       indent(1);
       if (put_xform(spec) < 0)
              return(MG_ETYPE);
       printf("%sDEF _xf%ld Group {\n", tabs, spec->xid);      /* begin */
       indent(1);
       return(MG_OK);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void indent ( int  deeper)

Definition at line 167 of file mgf2inv.c.

{
       static int    level;        /* current nesting level */
       register int  i;
       register char *cp;

       if (deeper) level++;        /* in or out? */
       else if (level > 0) level--;
                                   /* compute actual shift */
       if ((i = level) > MAXIND) i = MAXIND;
       cp = tabs;
       for (i *= SHIFTW; i >= TABSTOP; i -= TABSTOP)
              *cp++ = '\t';
       while (i--)
              *cp++ = ' ';
       *cp = '\0';
}

Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 
)

Definition at line 78 of file mgf2inv.c.

{
       int    i;
                            /* initialize dispatch table */
       mg_ehand[MG_E_COMMENT] = i_comment;       /* we pass comments */
       mg_ehand[MG_E_COLOR] = c_hcolor;   /* they get color */
       mg_ehand[MG_E_CMIX] = c_hcolor;           /* they mix colors */
       mg_ehand[MG_E_CSPEC] = c_hcolor;   /* they get spectra */
       mg_ehand[MG_E_CXY] = c_hcolor;            /* they get chromaticities */
       mg_ehand[MG_E_CCT] = c_hcolor;            /* they get color temp's */
       mg_ehand[MG_E_CYL] = i_cyl;        /* we do cylinders */
       mg_ehand[MG_E_ED] = c_hmaterial;   /* they get emission */
       mg_ehand[MG_E_FACE] = i_face;             /* we do faces */
       mg_ehand[MG_E_MATERIAL] = c_hmaterial;    /* they get materials */
       mg_ehand[MG_E_NORMAL] = c_hvertex; /* they get normals */
       mg_ehand[MG_E_OBJECT] = i_object;  /* we track object names */
       mg_ehand[MG_E_POINT] = c_hvertex;  /* they get points */
       mg_ehand[MG_E_RD] = c_hmaterial;   /* they get diffuse refl. */
       mg_ehand[MG_E_RS] = c_hmaterial;   /* they get specular refl. */
       mg_ehand[MG_E_SIDES] = c_hmaterial;       /* they get # sides */
       mg_ehand[MG_E_SPH] = i_sph;        /* we do spheres */
       mg_ehand[MG_E_TD] = c_hmaterial;   /* they get diffuse trans. */
       mg_ehand[MG_E_TS] = c_hmaterial;   /* they get specular trans. */
       mg_ehand[MG_E_VERTEX] = c_hvertex; /* they get vertices */
       mg_ehand[MG_E_XF] = i_xf;          /* we track transforms */
       mg_init();           /* initialize the parser */
                            /* get options and print format line */
       for (i = 1; i < argc && argv[i][0] == '-'; i++)
              if (!strcmp(argv[i], "-vrml"))
                     outtype = O_VRML1;
              else if (!strcmp(argv[i], "-1"))
                     outtype = O_INV1;
              else if (!strcmp(argv[i], "-2"))
                     outtype = O_INV2;
              else
                     goto userr;
       switch (outtype) {
       case O_INV1:
              printf("#Inventor V1.0 ascii\n");
              break;
       case O_INV2:
              printf("#Inventor V2.0 ascii\n");
              break;
       case O_VRML1:
              printf("#VRML V1.0 ascii\n");
              break;
       }
       printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
       printf("Separator {\n");           /* begin root node */
                                          /* general properties */
       printf("MaterialBinding { value OVERALL }\n");
       printf("NormalBinding { value PER_VERTEX_INDEXED }\n");
       if (outtype != O_INV1) {
              printf("ShapeHints {\n");
              printf("\tvertexOrdering CLOCKWISE\n");
              printf("\tfaceType UNKNOWN_FACE_TYPE\n");
              printf("}\n");
       }
       if (i == argc) {     /* load standard input */
              if (mg_load(NULL) != MG_OK)
                     exit(1);
              if (mg_nunknown)
                     printf("## %s: %u unknown entities\n",
                                   argv[0], mg_nunknown);
       }
                            /* load MGF files */
       for ( ; i < argc; i++) {
              printf("## %s %s ##############################\n",
                            argv[0], argv[i]);
              mg_nunknown = 0;
              if (mg_load(argv[i]) != MG_OK)
                     exit(1);
              if (mg_nunknown)
                     printf("## %s %s: %u unknown entities\n",
                                   argv[0], argv[i], mg_nunknown);
       }
       flush_cache();              /* flush face cache, just in case */
       printf("}\n");              /* close root node */
       exit(0);
userr:
       fprintf(stderr, "%s: [-1|-2|-vrml] [file] ..\n", argv[0]);
       exit(1);
}

Here is the call graph for this function:

int put_material ( void  )

Definition at line 334 of file mgf2inv.c.

{
       char   *mname = curmatname;
       float  rgbval[3];

       if (!c_cmaterial->clock) {  /* current, just use it */
              printf("%sUSE %s\n", tabs, mname);
              return(0);
       }
                            /* else update definition */
       printf("%sDEF %s Group {\n", tabs, mname);
       indent(1);
       printf("%sMaterial {\n", tabs);
       indent(1);
       mgf2rgb(&c_cmaterial->rd_c, c_cmaterial->rd, rgbval);
       printf("%sambientColor %.4f %.4f %.4f\n", tabs,
                     rgbval[0], rgbval[1], rgbval[2]);
       printf("%sdiffuseColor %.4f %.4f %.4f\n", tabs,
                     rgbval[0], rgbval[1], rgbval[2]);
       if (c_cmaterial->rs > FTINY) {
              mgf2rgb(&c_cmaterial->rs_c, c_cmaterial->rs, rgbval);
              printf("%sspecularColor %.4f %.4f %.4f\n", tabs,
                            rgbval[0], rgbval[1], rgbval[2]);
              printf("%sshininess %.3f\n", tabs, 1.-sqrt(c_cmaterial->rs_a));
       }
       if (c_cmaterial->ed > FTINY) {
              mgf2rgb(&c_cmaterial->ed_c, 1.0, rgbval);
              printf("%semissiveColor %.4f %.4f %.4f\n", tabs,
                            rgbval[0], rgbval[1], rgbval[2]);
       }
       if (c_cmaterial->ts > FTINY)
              printf("%stransparency %.4f\n", tabs,
                            c_cmaterial->ts + c_cmaterial->td);
       indent(0);
       printf("%s}\n", tabs);
       if (outtype != O_INV1)
              printf("%sShapeHints { shapeType %s faceType UNKNOWN_FACE_TYPE }\n",
                     tabs,
                     c_cmaterial->sided ? "SOLID" : "UNKNOWN_SHAPE_TYPE");
       indent(0);
       printf("%s}\n", tabs);
       c_cmaterial->clock = 0;
       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int put_xform ( register XF_SPEC spec)

Definition at line 302 of file mgf2inv.c.

{
       register char **av;
       register int  n;

       n = xf_ac(spec) - xf_ac(spec->prev);
       if (xf(&spec->xf, n, av=xf_av(spec)) != n)
              return(-1);
       printf("%sMatrixTransform {\n", tabs);
       indent(1);
       printf("%s# xf", tabs);            /* put out original as comment */
       while (n--) {
              putchar(' ');
              fputs(*av++, stdout);
       }
       putchar('\n');                     /* put out computed matrix */
       printf("%smatrix %13.9g %13.9g %13.9g %13.9g\n", tabs,
                     spec->xf.xfm[0][0], spec->xf.xfm[0][1],
                     spec->xf.xfm[0][2], spec->xf.xfm[0][3]);
       for (n = 1; n < 4; n++)
              printf("%s       %13.9g %13.9g %13.9g %13.9g\n", tabs,
                            spec->xf.xfm[n][0], spec->xf.xfm[n][1],
                            spec->xf.xfm[n][2], spec->xf.xfm[n][3]);
       indent(0);
       printf("%s}\n", tabs);
       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char * to_id ( register char *  name)

Definition at line 512 of file mgf2inv.c.

{
       static char   id[MAXID];
       register char *cp;

       for (cp = id; *name && cp < MAXID-1+id; name++)
              if (isalnum(*name) || *name == '_')
                     *cp++ = *name;
              else
                     *cp++ = '_';
       *cp = '\0';
       return(id);
}

Here is the caller graph for this function:


Variable Documentation

struct face * flast
struct face * flist
int nverts

Definition at line 40 of file mgf2inv.c.

int outtype = O_INV2

Definition at line 62 of file mgf2inv.c.

const char RCSid[] = "$Id: mgf2inv.c,v 1.11 2003/11/15 17:54:06 schorsch Exp $" [static]

Definition at line 2 of file mgf2inv.c.

char tabs[MAXIND *SHIFTW+1]

Definition at line 58 of file mgf2inv.c.

LUTAB vert_tab = LU_SINIT(NULL,NULL)

Definition at line 42 of file mgf2inv.c.

Definition at line 39 of file mgf2inv.c.