home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 8
/
CDASC08.ISO
/
NEWS
/
RADIANCE
/
SRC
/
GEN
/
XFORM.C
< prev
Wrap
C/C++ Source or Header
|
1993-10-07
|
15KB
|
694 lines
/* Copyright (c) 1992 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)xform.c 2.7 10/2/92 LBL";
#endif
/*
* xform.c - program to transform object files.
* Transformations must preserve aspect ratio.
*
* 10/19/85
* 11/6/86 Finally added error checking!
*/
#include "standard.h"
#include <ctype.h>
#include "object.h"
#include "otypes.h"
int xac; /* global xform argument count */
char **xav; /* global xform argument pointer */
int xfa; /* start of xf arguments */
XF tot; /* total transformation */
int reverse; /* boolean true if scene mirrored */
int invert = 0; /* boolean true to invert surfaces */
int expand = 0; /* boolean true to expand commands */
char *newmod = NULL; /* new modifier for surfaces */
char *idprefix = NULL; /* prefix for object identifiers */
#define ALIAS NUMOTYPE /* put alias at end of array */
#define NUMTYPES (NUMOTYPE+1) /* total number of object types */
FUN ofun[NUMTYPES] = INIT_OTYPE; /* default types and actions */
short tinvers[NUMOTYPE]; /* inverse types for surfaces */
extern char *malloc(), *fgetword();
#define progname (xav[0])
main(argc, argv) /* get transform options and transform file */
int argc;
char *argv[];
{
FILE *fopen();
FILE *fp;
int a;
/* check for array */
for (a = 1; a < argc; a++)
if (!strcmp(argv[a], "-a"))
return(doarray(argc, argv, a));
initotypes();
for (a = 1; a < argc; a++) {
if (argv[a][0] == '-')
switch (argv[a][1]) {
case 'm':
if (argv[a][2] || a+1 >= argc)
break;
newmod = argv[++a];
continue;
case 'n':
if (argv[a][2] || a+1 >= argc)
break;
idprefix = argv[++a];
continue;
case 'e':
if (argv[a][2])
break;
expand = 1;
continue;
case 'I':
if (argv[a][2])
break;
invert = 1;
continue;
}
break;
}
xav = argv;
xfa = a;
a += xf(&tot, argc-a, argv+a);
if (reverse = tot.sca < 0.0)
tot.sca = -tot.sca;
if (invert)
reverse = !reverse;
if (a < argc && argv[a][0] == '-') {
fprintf(stderr, "%s: command line error at '%s'\n",
argv[0], argv[a]);
exit(1);
}
xac = a;
/* simple header */
putchar('#');
for (a = 0; a < xac; a++)
printf(" %s", xav[a]);
putchar('\n');
/* transform input */
if (xac == argc)
xform("standard input", stdin);
else
for (a = xac; a < argc; a++) {
if ((fp = fopen(argv[a], "r")) == NULL) {
fprintf(stderr, "%s: cannot open \"%s\"\n",
progname, argv[a]);
exit(1);
}
xform(argv[a], fp);
fclose(fp);
}
return(0);
}
doarray(ac, av, ai) /* make array */
char **av;
int ac, ai;
{
char *newav[256], **avp;
char newid[128], repts[32];
char *oldid = NULL;
int i, err;
avp = newav+2;
avp[0] = av[0];
for (i = 1; i < ac; i++)
if (!strcmp(av[i-1], "-n")) {
oldid = av[i];
avp[i] = newid;
} else
avp[i] = av[i];
avp[ai] = "-i";
avp[ai+1] = repts;
avp[i] = NULL;
if (oldid == NULL) {
newav[0] = av[0];
newav[1] = "-n";
newav[2] = newid;
avp = newav;
ac += 2;
}
err = 0;
for (i = 0; i < atoi(av[ai+1]); i++) {
if (oldid == NULL)
sprintf(newid, "a%d", i);
else
sprintf(newid, "%s.%d", oldid, i);
sprintf(repts, "%d", i);
err |= main(ac, avp);
}
return(err);
}
xform(name, fin) /* transform stream by tot.xfm */
char *name;
register FILE *fin;
{
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);
xfcomm(name, fin);
} else { /* object */
ungetc(c, fin);
xfobject(name, fin);
}
}
}
xfcomm(fname, fin) /* transform a command */
char *fname;
FILE *fin;
{
FILE *popen();
char *fgetline();
FILE *pin;
char buf[512];
int i;
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);
}
xform(buf, pin);
pclose(pin);
} else {
printf("\n%s", buf);
if (xac > 1) {
printf(" | %s -e", xav[0]);
for (i = 1; i < xac; i++)
printf(" %s", xav[i]);
}
putchar('\n');
}
}
xfobject(fname, fin) /* transform an object */
char *fname;
FILE *fin;
{
extern char *strcpy();
char typ[16], nam[MAXSTR];
int fn;
/* modifier and type */
strcpy(typ, "EOF");
fgetword(nam, sizeof(nam), fin);
fgetword(typ, sizeof(typ), fin);
if ((fn = otype(typ)) < 0) {
fprintf(stderr, "%s: (%s): unknown object type \"%s\"\n",
progname, fname, typ);
exit(1);
}
if (ismodifier(fn))
printf("\n%s %s ", nam, typ);
else
printf("\n%s %s ", newmod != NULL ? newmod : nam,
invert ? ofun[tinvers[fn]].funame : typ);
/* object name */
fgetword(nam, sizeof(nam), fin);
if (idprefix == NULL || ismodifier(fn))
printf("%s\n", nam);
else
printf("%s.%s\n", idprefix, nam);
/* transform arguments */
if ((*ofun[fn].funp)(fin) < 0) {
fprintf(stderr, "%s: (%s): bad %s \"%s\"\n",
progname, fname, ofun[fn].funame, nam);
exit(1);
}
}
o_default(fin) /* pass on arguments unchanged */
FILE *fin;
{
register int i;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
/* string arguments */
printf("%d", fa.nsargs);
for (i = 0; i < fa.nsargs; i++)
printf(" %s", fa.sarg[i]);
printf("\n");
#ifdef IARGS
/* integer arguments */
printf("%d", fa.niargs);
for (i = 0; i < fa.niargs; i++)
printf(" %d", fa.iarg[i]);
printf("\n");
#else
printf("0\n");
#endif
/* float arguments */
printf("%d", fa.nfargs);
for (i = 0; i < fa.nfargs; i++)
printf(" %18.12g", fa.farg[i]);
printf("\n");
freefargs(&fa);
return(0);
}
addxform(fin) /* add xf arguments to strings */
FILE *fin;
{
register int i;
int resetarr = 0;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
/* string arguments */
if (xac > xfa && strcmp(xav[xfa], "-i"))
resetarr = 2;
printf("%d", fa.nsargs + resetarr + xac-xfa);
for (i = 0; i < fa.nsargs; i++)
printf(" %s", fa.sarg[i]);
if (resetarr)
printf(" -i 1");
for (i = xfa; i < xac; i++) /* add xf arguments */
printf(" %s", xav[i]);
printf("\n");
#ifdef IARGS
/* integer arguments */
printf("%d", fa.niargs);
for (i = 0; i < fa.niargs; i++)
printf(" %d", fa.iarg[i]);
printf("\n");
#else
printf("0\n");
#endif
/* float arguments */
printf("%d", fa.nfargs);
for (i = 0; i < fa.nfargs; i++)
printf(" %18.12g", fa.farg[i]);
printf("\n");
freefargs(&fa);
return(0);
}
int
otype(ofname) /* get object function number from its name */
register char *ofname;
{
register int i;
for (i = 0; i < NUMTYPES; i++)
if (!strcmp(ofun[i].funame, ofname))
return(i);
return(-1); /* not found */
}
alias(fin) /* transfer alias */
FILE *fin;
{
char aliasnm[MAXSTR];
if (fgetword(aliasnm, MAXSTR, fin) == NULL)
return(-1);
printf("\t%s\n", aliasnm);
return(0);
}
m_glow(fin) /* transform arguments for proximity light */
FILE *fin;
{
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 4)
return(-1);
printf("0\n0\n4");
printf(" %18.12g %18.12g %18.12g",
fa.farg[0], fa.farg[1], fa.farg[2]);
printf(" %18.12g\n", fa.farg[3] * tot.sca);
freefargs(&fa);
return(0);
}
m_spot(fin) /* transform arguments for spotlight */
FILE *fin;
{
FVECT v;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 7)
return(-1);
printf("0\n0\n7");
printf(" %18.12g %18.12g %18.12g %18.12g\n",
fa.farg[0], fa.farg[1], fa.farg[2], fa.farg[3]);
multv3(v, fa.farg+4, tot.xfm);
printf("\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
freefargs(&fa);
return(0);
}
m_dielectric(fin) /* transform arguments for dielectric */
FILE *fin;
{
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 5)
return(-1);
printf("0\n0\n5");
printf(" %18.12g %18.12g %18.12g",
pow(fa.farg[0], 1.0/tot.sca),
pow(fa.farg[1], 1.0/tot.sca),
pow(fa.farg[2], 1.0/tot.sca));
printf(" %18.12g %18.12g\n", fa.farg[3], fa.farg[4]);
freefargs(&fa);
return(0);
}
m_interface(fin) /* transform arguments for interface */
FILE *fin;
{
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 8)
return(-1);
printf("0\n0\n8\n");
printf("%18.12g %18.12g %18.12g",
pow(fa.farg[0], 1.0/tot.sca),
pow(fa.farg[1], 1.0/tot.sca),
pow(fa.farg[2], 1.0/tot.sca));
printf(" %18.12g\n", fa.farg[3]);
printf("%18.12g %18.12g %18.12g",
pow(fa.farg[4], 1.0/tot.sca),
pow(fa.farg[5], 1.0/tot.sca),
pow(fa.farg[6], 1.0/tot.sca));
printf(" %18.12g\n", fa.farg[7]);
freefargs(&fa);
return(0);
}
text(fin) /* transform text arguments */
FILE *fin;
{
int i;
FVECT v;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nfargs < 9)
return(-1);
/* string arguments */
printf("%d", fa.nsargs);
for (i = 0; i < fa.nsargs; i++)
printf(" %s", fa.sarg[i]);
printf("\n0\n%d\n", fa.nfargs);
/* anchor point */
multp3(v, fa.farg, tot.xfm);
printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
/* right vector */
multv3(v, fa.farg+3, tot.xfm);
printf(" %18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
/* down vector */
multv3(v, fa.farg+6, tot.xfm);
printf(" %18.12g %18.12g %18.12g", v[0], v[1], v[2]);
/* remaining arguments */
for (i = 9; i < fa.nfargs; i++) {
if (i%3 == 0)
putchar('\n');
printf(" %18.12g", fa.farg[i]);
}
putchar('\n');
freefargs(&fa);
return(0);
}
o_source(fin) /* transform source arguments */
FILE *fin;
{
FVECT dv;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 4)
return(-1);
/* transform direction vector */
multv3(dv, fa.farg, tot.xfm);
/* output */
printf("0\n0\n4");
printf(" %18.12g %18.12g %18.12g %18.12g\n",
dv[0], dv[1], dv[2], fa.farg[3]);
freefargs(&fa);
return(0);
}
o_sphere(fin) /* transform sphere arguments */
FILE *fin;
{
FVECT cent;
double rad;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 4)
return(-1);
multp3(cent, fa.farg, tot.xfm); /* transform center */
rad = fa.farg[3] * tot.sca; /* scale radius */
printf("0\n0\n4");
printf(" %18.12g %18.12g %18.12g %18.12g\n",
cent[0], cent[1], cent[2], rad);
freefargs(&fa);
return(0);
}
o_face(fin) /* transform face arguments */
FILE *fin;
{
FVECT p;
register int i;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs % 3)
return(-1);
printf("0\n0\n%d\n", fa.nfargs);
for (i = 0; i < fa.nfargs; i += 3) {
if (reverse)
multp3(p, fa.farg+(fa.nfargs-i-3), tot.xfm);
else
multp3(p, fa.farg+i, tot.xfm);
printf(" %18.12g %18.12g %18.12g\n", p[0], p[1], p[2]);
}
freefargs(&fa);
return(0);
}
o_cone(fin) /* transform cone and cup arguments */
FILE *fin;
{
FVECT p0, p1;
double r0, r1;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 8)
return(-1);
printf("0\n0\n8\n");
multp3(p0, fa.farg, tot.xfm);
multp3(p1, fa.farg+3, tot.xfm);
r0 = fa.farg[6] * tot.sca;
r1 = fa.farg[7] * tot.sca;
printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
printf(" %18.12g %18.12g\n", r0, r1);
freefargs(&fa);
return(0);
}
o_cylinder(fin) /* transform cylinder and tube arguments */
FILE *fin;
{
FVECT p0, p1;
double rad;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 7)
return(-1);
printf("0\n0\n7\n");
multp3(p0, fa.farg, tot.xfm);
multp3(p1, fa.farg+3, tot.xfm);
rad = fa.farg[6] * tot.sca;
printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
printf(" %18.12g %18.12g %18.12g\n", p1[0], p1[1], p1[2]);
printf(" %18.12g\n", rad);
freefargs(&fa);
return(0);
}
o_ring(fin) /* transform ring arguments */
FILE *fin;
{
FVECT p0, pd;
double r0, r1;
FUNARGS fa;
if (readfargs(&fa, fin) != 1)
return(-1);
if (fa.nsargs != 0 || fa.nfargs != 8)
return(-1);
printf("0\n0\n8\n");
multp3(p0, fa.farg, tot.xfm);
multv3(pd, fa.farg+3, tot.xfm);
if (invert) {
pd[0] = -pd[0];
pd[1] = -pd[1];
pd[2] = -pd[2];
}
r0 = fa.farg[6] * tot.sca;
r1 = fa.farg[7] * tot.sca;
printf(" %18.12g %18.12g %18.12g\n", p0[0], p0[1], p0[2]);
printf(" %18.12g %18.12g %18.12g\n", pd[0], pd[1], pd[2]);
printf(" %18.12g %18.12g\n", r0, r1);
freefargs(&fa);
return(0);
}
initotypes() /* initialize ofun[] array */
{
extern int o_source();
extern int o_sphere();
extern int o_face();
extern int o_cone();
extern int o_cylinder();
extern int o_ring();
extern int m_glow();
extern int m_spot();
extern int m_dielectric();
extern int m_interface();
extern int text();
extern int alias();
extern int passargs();
extern int addxform();
register int i;
if (ofun[OBJ_SOURCE].funp == o_source)
return; /* done already */
/* alias is additional */
ofun[ALIAS].funame = ALIASID;
ofun[ALIAS].flags = 0;
/* functions get new transform */
for (i = 0; i < NUMTYPES; i++)
if (hasfunc(i))
ofun[i].funp = addxform;
/* special cases */
ofun[OBJ_SOURCE].funp = o_source;
ofun[OBJ_SPHERE].funp =
ofun[OBJ_BUBBLE].funp = o_sphere;
ofun[OBJ_FACE].funp = o_face;
ofun[OBJ_CONE].funp =
ofun[OBJ_CUP].funp = o_cone;
ofun[OBJ_CYLINDER].funp =
ofun[OBJ_TUBE].funp = o_cylinder;
ofun[OBJ_RING].funp = o_ring;
ofun[OBJ_INSTANCE].funp = addxform;
ofun[MAT_GLOW].funp = m_glow;
ofun[MAT_SPOT].funp = m_spot;
ofun[MAT_DIELECTRIC].funp = m_dielectric;
ofun[MAT_INTERFACE].funp = m_interface;
ofun[PAT_CTEXT].funp =
ofun[PAT_BTEXT].funp =
ofun[MIX_TEXT].funp = text;
ofun[ALIAS].funp = alias;
/* surface inverses */
tinvers[OBJ_SOURCE] = OBJ_SOURCE;
tinvers[OBJ_CONE] = OBJ_CUP;
tinvers[OBJ_CUP] = OBJ_CONE;
tinvers[OBJ_SPHERE] = OBJ_BUBBLE;
tinvers[OBJ_BUBBLE] = OBJ_SPHERE;
tinvers[OBJ_RING] = OBJ_RING;
tinvers[OBJ_CYLINDER] = OBJ_TUBE;
tinvers[OBJ_TUBE] = OBJ_CYLINDER;
tinvers[OBJ_INSTANCE] = OBJ_INSTANCE; /* oh, well */
}