Back to index

radiance  4R0+20100331
Classes | Defines | Functions | Variables
replmarks.c File Reference
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include "platform.h"
#include "rtio.h"
#include "rtprocess.h"
#include "fvect.h"

Go to the source code of this file.

Classes

struct  EDGE
struct  mrkr

Defines

#define PI   3.14159265358979323846
#define FEQ(a, b)   ((a)-(b) <= 1e-7 && (b)-(a) <= 1e-7)
#define MAXVERT   6 /* maximum number of vertices for markers */
#define MAXMARK   128 /* maximum number of markers */
#define USE_XFORM   1 /* use !xform inline command */
#define USE_INSTANCE   2 /* use instance primitive */
#define USE_MESH   3 /* use mesh primitive */

Functions

static void convert (char *name, FILE *fin)
static void cvcomm (char *fname, FILE *fin)
static void cvobject (char *fname, FILE *fin)
static void replace (char *fname, struct mrkr *m, char *mark, FILE *fin)
static int edgecmp (const void *e1, const void *e2)
static int buildxf (char *xf, double markscale, FILE *fin)
static int addrot (char *xf, FVECT xp, FVECT yp, FVECT zp)
int main (int argc, char *argv[])
void convert (char *name, register FILE *fin)
void replace (char *fname, register struct mrkr *m, char *mark, FILE *fin)
int buildxf (register char *xf, double markscale, FILE *fin)
int addrot (register char *xf, FVECT xp, FVECT yp, FVECT zp)

Variables

static const char RCSid [] = "$Id: replmarks.c,v 2.15 2008/01/25 02:11:13 greg Exp $"
struct mrkr marker [MAXMARK+1]
int nmarkers = 0
int expand
char * progname

Class Documentation

struct EDGE

Definition at line 35 of file replmarks.c.

Class Members
short beg
short end
float len2
struct mrkr

Definition at line 40 of file replmarks.c.

Class Members
char * modin
char * modout
double mscale
char * objname
int usetype

Define Documentation

#define FEQ (   a,
 
)    ((a)-(b) <= 1e-7 && (b)-(a) <= 1e-7)

Definition at line 26 of file replmarks.c.

#define MAXMARK   128 /* maximum number of markers */

Definition at line 29 of file replmarks.c.

#define MAXVERT   6 /* maximum number of vertices for markers */

Definition at line 28 of file replmarks.c.

#define PI   3.14159265358979323846

Definition at line 23 of file replmarks.c.

#define USE_INSTANCE   2 /* use instance primitive */

Definition at line 32 of file replmarks.c.

#define USE_MESH   3 /* use mesh primitive */

Definition at line 33 of file replmarks.c.

#define USE_XFORM   1 /* use !xform inline command */

Definition at line 31 of file replmarks.c.


Function Documentation

static int addrot ( char *  xf,
FVECT  xp,
FVECT  yp,
FVECT  zp 
) [static]
int addrot ( register char *  xf,
FVECT  xp,
FVECT  yp,
FVECT  zp 
)

Definition at line 384 of file replmarks.c.

{
       int    n;
       double theta;

       if (yp[2]*yp[2] + zp[2]*zp[2] < 2.*FTINY*FTINY) {
              /* Special case for X' along Z-axis */
              theta = -atan2(yp[0], yp[1]);
              sprintf(xf, " -ry %f -rz %f",
                            xp[2] < 0.0 ? 90.0 : -90.0,
                            theta*(180./PI));
              return(4);
       }
       n = 0;
       theta = atan2(yp[2], zp[2]);
       if (!FEQ(theta,0.0)) {
              sprintf(xf, " -rx %f", theta*(180./PI));
              while (*xf) ++xf;
              n += 2;
       }
       theta = asin(-xp[2]);
       if (!FEQ(theta,0.0)) {
              sprintf(xf, " -ry %f", theta*(180./PI));
              while (*xf) ++xf;
              n += 2;
       }
       theta = atan2(xp[1], xp[0]);
       if (!FEQ(theta,0.0)) {
              sprintf(xf, " -rz %f", theta*(180./PI));
              /* while (*xf) ++xf; */
              n += 2;
       }
       return(n);
}

Here is the call graph for this function:

static int buildxf ( char *  xf,
double  markscale,
FILE *  fin 
) [static]

Here is the caller graph for this function:

int buildxf ( register char *  xf,
double  markscale,
FILE *  fin 
)

Definition at line 301 of file replmarks.c.

{
       static FVECT  vlist[MAXVERT];
       static EDGE   elist[MAXVERT];
       FVECT  xvec, yvec, zvec;
       double xlen;
       int    n;
       register int  i;
       /*
        * Read and sort vectors:  longest is hypotenuse,
        *     second longest is x' axis,
        *     third longest is y' axis (approximate),
        *     other vectors are ignored.
        * It is an error if the x' and y' axes do
        *     not share a common vertex (their origin).
        */
       if (fscanf(fin, "%*d %*d %d", &n) != 1)
              return(-1);
       if (n%3 != 0)
              return(-1);
       n /= 3;
       if (n < 3 || n > MAXVERT)
              return(-1);
                                   /* sort edges in descending order */
       for (i = 0; i < n; i++) {
              if (fscanf(fin, "%lf %lf %lf", &vlist[i][0],
                            &vlist[i][1], &vlist[i][2]) != 3)
                     return(-1);
              if (i) {
                     elist[i].beg = i-1;
                     elist[i].end = i;
                     elist[i].len2 = dist2(vlist[i-1],vlist[i]);
              }
       }
       elist[0].beg = n-1;
       elist[0].end = 0;
       elist[0].len2 = dist2(vlist[n-1],vlist[0]);
       qsort(elist, n, sizeof(EDGE), edgecmp);
                                   /* find x' and y' */
       if (elist[1].end == elist[2].beg || elist[1].end == elist[2].end) {
              i = elist[1].beg;
              elist[1].beg = elist[1].end;
              elist[1].end = i;
       }
       if (elist[2].end == elist[1].beg) {
              i = elist[2].beg;
              elist[2].beg = elist[2].end;
              elist[2].end = i;
       }
       if (elist[1].beg != elist[2].beg)
              return(-1);          /* x' and y' not connected! */
       for (i = 0; i < 3; i++) {
              xvec[i] = vlist[elist[1].end][i] - vlist[elist[1].beg][i];
              yvec[i] = vlist[elist[2].end][i] - vlist[elist[2].beg][i];
       }
       if ((xlen = normalize(xvec)) == 0.0)
              return(-1);
       fcross(zvec, xvec, yvec);
       if (normalize(zvec) == 0.0)
              return(-1);
       fcross(yvec, zvec, xvec);
       n = 0;                      /* start transformation... */
       if (markscale > 0.0) {             /* add scale factor */
              sprintf(xf, " -s %f", xlen*markscale);
              n += 2;
              while (*xf) ++xf;
       }
                                   /* add rotation */
       n += addrot(xf, xvec, yvec, zvec);
       while (*xf) ++xf;
                                   /* add translation */
       n += 4;
       sprintf(xf, " -t %f %f %f", vlist[elist[1].beg][0],
                     vlist[elist[1].beg][1], vlist[elist[1].beg][2]);
       return(n);                  /* all done */
}

Here is the call graph for this function:

static void convert ( char *  name,
FILE *  fin 
) [static]

Definition at line 116 of file tmesh2rad.c.

{
       char   typ[4];
       int    id[3];
       double vec[3];
       char   picfile[128];
       char   matname[64];
       char   objname[64];
       register int  i;
       register VERTEX      *lastv;
                                   /* start fresh */
       i = nverts;
       lastv = vlist;
       while (i--)
              (lastv++)->flags = 0;
       lastv = NULL;
       strcpy(picfile, defpat);
       strcpy(matname, defmat);
       strcpy(objname, defobj);

       printf("\n## T-mesh read from: %s\n", fname);
                                   /* scan until EOF */
       while (fscanf(fp, "%1s", typ) == 1)
              switch (typ[0]) {
              case 'v':            /* vertex */
                     if (fscanf(fp, "%d %lf %lf %lf", &id[0],
                                   &vec[0], &vec[1], &vec[2]) != 4)
                            syntax(fname, fp, "Bad vertex");
                     lastv = vnew(id[0], vec[0], vec[1], vec[2]);
                     break;
              case 't':            /* triangle */
                     if (fscanf(fp, "%d %d %d", &id[0], &id[1], &id[2]) != 3)
                            syntax(fname, fp, "Bad triangle");
                     if (novert(id[0]) | novert(id[1]) | novert(id[2]))
                            syntax(fname, fp, "Undefined triangle vertex");
                     triangle(picfile, matname, objname, &vlist[id[0]],
                                   &vlist[id[1]], &vlist[id[2]]);
                     break;
              case 'n':            /* surface normal */
                     if (lastv == NULL)
                            syntax(fname, fp, "No vertex for normal");
                     if (fscanf(fp, "%lf %lf %lf",
                                   &vec[0], &vec[1], &vec[2]) != 3)
                            syntax(fname, fp, "Bad vertex normal");
                     lastv->nor[0] = vec[0];
                     lastv->nor[1] = vec[1];
                     lastv->nor[2] = vec[2];
                     if (normalize(lastv->nor) == 0.0)
                            syntax(fname, fp, "Zero vertex normal");
                     lastv->flags |= V_HASNORM;
                     break;
              case 'i':            /* index position */
                     if (lastv == NULL)
                            syntax(fname, fp, "No vertex for index");
                     if (fscanf(fp, "%lf %lf", &vec[0], &vec[1]) != 2)
                            syntax(fname, fp, "Bad index");
                     lastv->ndx[0] = vec[0];
                     lastv->ndx[1] = vec[1];
                     lastv->flags |= V_HASINDX;
                     break;
              case 'o':            /* object name */
                     if (fscanf(fp, "%s", objname) != 1)
                            syntax(fname, fp, "Bad object name");
                     break;
              case 'm':            /* material */
                     if (fscanf(fp, "%s", matname) != 1)
                            syntax(fname, fp, "Bad material");
                     if (matname[0] == '-' && !matname[1])
                            strcpy(matname, VOIDID);
                     break;
              case 'p':            /* picture */
                     if (fscanf(fp, "%s", picfile) != 1)
                            syntax(fname, fp, "Bad pattern");
                     if (picfile[0] == '-' && !picfile[1])
                            picfile[0] = '\0';
                     break;
              case '#':            /* comment */
                     fputs("\n#", stdout);
                     while ((i = getc(fp)) != EOF) {
                            putchar(i);
                            if (i == '\n')
                                   break;
                     }
                     break;
              default:
                     syntax(fname, fp, "Unknown type");
                     break;
              }
}

Here is the call graph for this function:

void convert ( char *  name,
register FILE *  fin 
)

Definition at line 142 of file replmarks.c.

{
       register int  c;

       while ((c = getc(fin)) != EOF) {
              if (isspace(c))                           /* blank */
                     continue;
              if (c == '#') {                           /* comment */
                     putchar(c);
                     do {
                            if ((c = getc(fin)) == EOF)
                                   return;
                            putchar(c);
                     } while (c != '\n');
              } else if (c == '!') {                    /* command */
                     ungetc(c, fin);
                     cvcomm(name, fin);
              } else {                           /* object */
                     ungetc(c, fin);
                     cvobject(name, fin);
              }
       }
}

Here is the call graph for this function:

void cvcomm ( char *  fname,
FILE *  fin 
) [static]

Definition at line 171 of file replmarks.c.

{
       FILE   *pin;
       char   buf[512], *fgetline();

       fgetline(buf, sizeof(buf), fin);
       if (expand) {
              if ((pin = popen(buf+1, "r")) == NULL) {
                     fprintf(stderr,
                     "%s: (%s): cannot execute \"%s\"\n",
                                   progname, fname, buf);
                     exit(1);
              }
              convert(buf, pin);
              pclose(pin);
       } else
              printf("\n%s\n", buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void cvobject ( char *  fname,
FILE *  fin 
) [static]

Definition at line 195 of file replmarks.c.

{
       extern char   *fgetword();
       char   buf[128], typ[16], nam[128];
       int    i, n;
       register int  j;

       if (fgetword(buf, sizeof(buf), fin) == NULL ||
                     fgetword(typ, sizeof(typ), fin) == NULL ||
                     fgetword(nam, sizeof(nam), fin) == NULL)
              goto readerr;
       if (!strcmp(typ, "polygon"))
              for (j = 0; j < nmarkers; j++)
                     if (!strcmp(buf, marker[j].modin)) {
                            replace(fname, &marker[j], nam, fin);
                            return;
                     }
       putchar('\n'); fputword(buf, stdout);
       printf(" %s ", typ);
       fputword(nam, stdout); putchar('\n');
       if (!strcmp(typ, "alias")) {              /* alias special case */
              if (fgetword(buf, sizeof(buf), fin) == NULL)
                     goto readerr;
              putchar('\t'); fputword(buf, stdout); putchar('\n');
              return;
       }
       for (i = 0; i < 3; i++) {          /* pass along arguments */
              if (fscanf(fin, "%d", &n) != 1)
                     goto readerr;
              printf("%d", n);
              for (j = 0; j < n; j++) {
                     if (fgetword(buf, sizeof(buf), fin) == NULL)
                            goto readerr;
                     if (j%3 == 0)
                            putchar('\n');
                     putchar('\t');
                     fputword(buf, stdout);
              }
              putchar('\n');
       }
       return;
readerr:
       fprintf(stderr, "%s: (%s): read error for %s \"%s\"\n",
                     progname, fname, typ, nam);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int edgecmp ( const void *  e1,
const void *  e2 
) [static]

Definition at line 287 of file replmarks.c.

{
       if (((EDGE*)e1)->len2 > ((EDGE*)e2)->len2)
              return(-1);
       if (((EDGE*)e1)->len2 < ((EDGE*)e2)->len2)
              return(1);
       return(0);
}

Here is the caller graph for this function:

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

Definition at line 63 of file replmarks.c.

{
       FILE   *fp;
       int    i, j;

       progname = argv[0];
       i = 1;
       while (i < argc && argv[i][0] == '-') {
              do {
                     switch (argv[i][1]) {
                     case 'i':
                            marker[nmarkers].usetype = USE_INSTANCE;
                            marker[nmarkers].objname = argv[++i];
                            break;
                     case 'I':
                            marker[nmarkers].usetype = USE_MESH;
                            marker[nmarkers].objname = argv[++i];
                            break;
                     case 'x':
                            marker[nmarkers].usetype = USE_XFORM;
                            marker[nmarkers].objname = argv[++i];
                            break;
                     case 'e':
                            expand = 1;
                            break;
                     case 'm':
                            marker[nmarkers].modout = argv[++i];
                            break;
                     case 's':
                            marker[nmarkers].mscale = atof(argv[++i]);
                            break;
                     default:
                            goto userr;
                     }
                     if (++i >= argc)
                            goto userr;
              } while (argv[i][0] == '-');
              if (marker[nmarkers].objname == NULL)
                     goto userr;
              if (nmarkers >= MAXMARK) {
                     fprintf(stderr, "%s: too many markers\n", progname);
                     return 1;
              }
              marker[nmarkers++].modin = argv[i++];
              marker[nmarkers].mscale = marker[nmarkers-1].mscale;
       }
       if (nmarkers == 0)
              goto userr;
                                   /* simple header */
       putchar('#');
       for (j = 0; j < i; j++) {
              putchar(' ');
              fputs(argv[j], stdout);
       }
       putchar('\n');
       if (i == argc)
              convert("<stdin>", stdin);
       else
              for ( ; i < argc; i++) {
                     if ((fp = fopen(argv[i], "r")) == NULL) {
                            perror(argv[i]);
                            exit(1);
                     }
                     convert(argv[i], fp);
                     fclose(fp);
              }
       return 0;
userr:
       fprintf(stderr,
"Usage: %s [-e][-s size][-m modout] {-x objfile|-i octree|-I mesh} modname .. [file ..]\n",
              progname);
       return 1;
}

Here is the call graph for this function:

static void replace ( char *  fname,
struct mrkr m,
char *  mark,
FILE *  fin 
) [static]

Here is the caller graph for this function:

void replace ( char *  fname,
register struct mrkr m,
char *  mark,
FILE *  fin 
)

Definition at line 246 of file replmarks.c.

{
       int    n;
       char   buf[256];

       buf[0] = '\0';                     /* bug fix thanks to schorsch */
       if (m->usetype == USE_XFORM) {
              sprintf(buf, "xform -n %s", mark);
              if (m->modout != NULL)
                     sprintf(buf+strlen(buf), " -m %s", m->modout);
              if (buildxf(buf+strlen(buf), m->mscale, fin) < 0)
                     goto badxf;
              sprintf(buf+strlen(buf), " %s", m->objname);
              if (expand) {
                     fflush(stdout);
                     system(buf);
              } else
                     printf("\n!%s\n", buf);
       } else {
              if ((n = buildxf(buf, m->mscale, fin)) < 0)
                     goto badxf;
              printf("\n%s %s %s\n",
                            m->modout==NULL?"void":m->modout,
                            m->usetype==USE_INSTANCE?"instance":"mesh",
                            mark);
              printf("%d %s%s\n0\n0\n", n+1, m->objname, buf);
       }
       return;
badxf:
       fprintf(stderr, "%s: (%s): bad arguments for marker \"%s\"\n",
                     progname, fname, mark);
       exit(1);
}

Here is the call graph for this function:


Variable Documentation

int expand

Definition at line 49 of file replmarks.c.

struct mrkr marker[MAXMARK+1]
int nmarkers = 0

Definition at line 47 of file replmarks.c.

char* progname

Definition at line 51 of file replmarks.c.

const char RCSid[] = "$Id: replmarks.c,v 2.15 2008/01/25 02:11:13 greg Exp $" [static]

Definition at line 2 of file replmarks.c.