--- ray/src/gen/replmarks.c 1991/11/12 17:04:51 2.1 +++ ray/src/gen/replmarks.c 2004/01/29 22:20:31 2.11 @@ -1,23 +1,24 @@ -/* Copyright (c) 1991 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id"; #endif - /* * Replace markers in Radiance scene description with objects or instances. * * Created: 17 Feb 1991 Greg Ward */ -#include +#include #include #include +#include +#include "platform.h" +#include "rtio.h" +#include "rtprocess.h" #include "fvect.h" #ifdef M_PI -#define PI M_PI +#define PI ((double)M_PI) #else #define PI 3.14159265358979323846 #endif @@ -25,59 +26,88 @@ static char SCCSid[] = "$SunId$ LBL"; #define FEQ(a,b) ((a)-(b) <= 1e-7 && (b)-(a) <= 1e-7) #define MAXVERT 6 /* maximum number of vertices for markers */ +#define MAXMARK 32 /* 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 */ + typedef struct { short beg, end; /* beginning and ending vertex */ float len2; /* length squared */ } EDGE; /* a marker edge */ -int expand = 0; /* expand commands? */ +struct mrkr { + char *modout; /* output modifier */ + double mscale; /* scale by this to get unit */ + char *modin; /* input modifier indicating marker */ + char *objname; /* output object file or octree */ + int usetype; /* one of USE_* above */ +} marker[MAXMARK]; /* array of markers */ +int nmarkers = 0; /* number of markers */ -char *modout = NULL; /* output modifier (for instances) */ +int expand; /* expand commands? */ -double markscale = 0.0; /* scale markers by this to get unit */ - -char *modin = NULL; /* input modifier indicating marker */ - -char *objname = NULL; /* output object file (octree if instance) */ -int doxform; /* true if xform, false if instance */ - char *progname; +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); -main(argc, argv) -int argc; -char *argv[]; + +int +main( + int argc, + char *argv[] +) { FILE *fp; int i, j; progname = argv[0]; - for (i = 1; i < argc && argv[i][0] == '-'; i++) - switch (argv[i][1]) { - case 'i': - doxform = 0; - objname = argv[++i]; - break; - case 'x': - doxform = 1; - objname = argv[++i]; - break; - case 'e': - expand = !expand; - break; - case 'm': - modout = argv[++i]; - break; - case 's': - markscale = atof(argv[++i]); - break; - default: + 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 (i < argc) - modin = argv[i++]; - if (objname == NULL || modin == NULL) + marker[nmarkers++].modin = argv[i++]; + if (nmarkers >= MAXMARK) + break; + marker[nmarkers].mscale = marker[nmarkers-1].mscale; + } + if (nmarkers == 0) goto userr; /* simple header */ putchar('#'); @@ -97,18 +127,20 @@ char *argv[]; convert(argv[i], fp); fclose(fp); } - exit(0); + return 0; userr: fprintf(stderr, -"Usage: %s [-e][-s size][-m modout] {-x objfile|-i octree} modname [file ..]\n", +"Usage: %s [-e][-s size][-m modout] {-x objfile|-i octree|-I mesh} modname .. [file ..]\n", progname); - exit(1); + return 1; } -convert(name, fin) /* replace marks in a stream */ -char *name; -register FILE *fin; +void +convert( /* replace marks in a stream */ + char *name, + register FILE *fin +) { register int c; @@ -133,11 +165,13 @@ register FILE *fin; } -cvcomm(fname, fin) /* convert a command */ -char *fname; -FILE *fin; +void +cvcomm( /* convert a command */ + char *fname, + FILE *fin +) { - FILE *pin, *popen(); + FILE *pin; char buf[512], *fgetline(); fgetline(buf, sizeof(buf), fin); @@ -155,19 +189,25 @@ FILE *fin; } -cvobject(fname, fin) /* convert an object */ -char *fname; -FILE *fin; +void +cvobject( /* convert an object */ + char *fname, + FILE *fin +) { + extern char *fgetword(); char buf[128], typ[16], nam[128]; - int i, j, n; + int i, n; + register int j; if (fscanf(fin, "%s %s %s", buf, typ, nam) != 3) goto readerr; - if (!strcmp(buf, modin) && !strcmp(typ, "polygon")) { - replace(fname, nam, fin); - return; - } + if (!strcmp(typ, "polygon")) + for (j = 0; j < nmarkers; j++) + if (!strcmp(buf, marker[j].modin)) { + replace(fname, &marker[j], nam, fin); + return; + } printf("\n%s %s %s\n", buf, typ, nam); if (!strcmp(typ, "alias")) { /* alias special case */ if (fscanf(fin, "%s", buf) != 1) @@ -180,11 +220,12 @@ FILE *fin; goto readerr; printf("%d", n); for (j = 0; j < n; j++) { - if (fscanf(fin, "%s", buf) != 1) + if (fgetword(buf, sizeof(buf), fin) == NULL) goto readerr; if (j%3 == 0) putchar('\n'); - printf("\t%s", buf); + putchar('\t'); + fputword(buf, stdout); } putchar('\n'); } @@ -195,30 +236,38 @@ readerr: } -replace(fname, mark, fin) /* replace marker */ -char *fname, *mark; -FILE *fin; +void +replace( /* replace marker */ + char *fname, + register struct mrkr *m, + char *mark, + FILE *fin +) { int n; char buf[256]; - if (doxform) { - sprintf(buf, "xform -e -n %s", mark); - if (modout != NULL) - sprintf(buf+strlen(buf), " -m %s", modout); - if (buildxf(buf+strlen(buf), fin) < 0) + 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", objname); + sprintf(buf+strlen(buf), " %s", m->objname); if (expand) { fflush(stdout); system(buf); } else printf("\n!%s\n", buf); } else { - if ((n = buildxf(buf, fin)) < 0) + if ((n = buildxf(buf, m->mscale, fin)) < 0) goto badxf; - printf("\n%s instance %s\n", modout==NULL?"void":modout, mark); - printf("%d %s%s\n0\n0\n", n+1, objname, buf); + 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: @@ -228,21 +277,26 @@ badxf: } -edgecmp(e1, e2) /* compare two edges, descending order */ -EDGE *e1, *e2; +int +edgecmp( /* compare two edges, descending order */ + const void *e1, + const void *e2 +) { - if (e1->len2 > e2->len2) + if (((EDGE*)e1)->len2 > ((EDGE*)e2)->len2) return(-1); - if (e1->len2 < e2->len2) + if (((EDGE*)e1)->len2 < ((EDGE*)e2)->len2) return(1); return(0); } int -buildxf(xf, fin) /* build transform for marker */ -char *xf; -FILE *fin; +buildxf( /* build transform for marker */ + register char *xf, + double markscale, + FILE *fin +) { static FVECT vlist[MAXVERT]; static EDGE elist[MAXVERT]; @@ -307,11 +361,11 @@ FILE *fin; if (markscale > 0.0) { /* add scale factor */ sprintf(xf, " -s %f", xlen*markscale); n += 2; - xf += strlen(xf); + while (*xf) ++xf; } /* add rotation */ n += addrot(xf, xvec, yvec, zvec); - xf += strlen(xf); + while (*xf) ++xf; /* add translation */ n += 4; sprintf(xf, " -t %f %f %f", vlist[elist[1].beg][0], @@ -320,9 +374,13 @@ FILE *fin; } -addrot(xf, xp, yp, zp) /* compute rotation (x,y,z) => (xp,yp,zp) */ -char *xf; -FVECT xp, yp, zp; +int +addrot( /* compute rotation (x,y,z) => (xp,yp,zp) */ + register char *xf, + FVECT xp, + FVECT yp, + FVECT zp +) { int n; double theta; @@ -331,19 +389,19 @@ FVECT xp, yp, zp; theta = atan2(yp[2], zp[2]); if (!FEQ(theta,0.0)) { sprintf(xf, " -rx %f", theta*(180./PI)); - xf += strlen(xf); + while (*xf) ++xf; n += 2; } theta = asin(-xp[2]); if (!FEQ(theta,0.0)) { sprintf(xf, " -ry %f", theta*(180./PI)); - xf += strlen(xf); + while (*xf) ++xf; n += 2; } theta = atan2(xp[1], xp[0]); if (!FEQ(theta,0.0)) { sprintf(xf, " -rz %f", theta*(180./PI)); - /* xf += strlen(xf); */ + /* while (*xf) ++xf; */ n += 2; } return(n);