--- ray/src/gen/replmarks.c 2003/11/16 10:29:38 2.9 +++ ray/src/gen/replmarks.c 2025/04/23 01:57:04 2.21 @@ -1,5 +1,5 @@ #ifndef lint -static const char RCSid[] = "$Id"; +static const char RCSid[] = "$Id: replmarks.c,v 2.21 2025/04/23 01:57:04 greg Exp $"; #endif /* * Replace markers in Radiance scene description with objects or instances. @@ -14,7 +14,7 @@ static const char RCSid[] = "$Id"; #include "platform.h" #include "rtio.h" -#include "rtprocess.h" +#include "paths.h" #include "fvect.h" #ifdef M_PI @@ -23,11 +23,13 @@ static const char RCSid[] = "$Id"; #define PI 3.14159265358979323846 #endif -#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 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 */ + typedef struct { short beg, end; /* beginning and ending vertex */ float len2; /* length squared */ @@ -38,8 +40,8 @@ struct mrkr { double mscale; /* scale by this to get unit */ char *modin; /* input modifier indicating marker */ char *objname; /* output object file or octree */ - int doxform; /* true if xform, false if instance */ -} marker[MAXMARK]; /* array of markers */ + int usetype; /* one of USE_* above */ +} marker[MAXMARK+1]; /* array of markers */ int nmarkers = 0; /* number of markers */ int expand; /* expand commands? */ @@ -70,11 +72,15 @@ main( do { switch (argv[i][1]) { case 'i': - marker[nmarkers].doxform = 0; + 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].doxform = 1; + marker[nmarkers].usetype = USE_XFORM; marker[nmarkers].objname = argv[++i]; break; case 'e': @@ -94,9 +100,11 @@ main( } 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++]; - if (nmarkers >= MAXMARK) - break; marker[nmarkers].mscale = marker[nmarkers-1].mscale; } if (nmarkers == 0) @@ -122,7 +130,7 @@ main( 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); return 1; } @@ -131,10 +139,10 @@ userr: void convert( /* replace marks in a stream */ char *name, - register FILE *fin + FILE *fin ) { - register int c; + int c; while ((c = getc(fin)) != EOF) { if (isspace(c)) /* blank */ @@ -164,7 +172,7 @@ cvcomm( /* convert a command */ ) { FILE *pin; - char buf[512], *fgetline(); + char buf[512]; fgetline(buf, sizeof(buf), fin); if (expand) { @@ -175,7 +183,10 @@ cvcomm( /* convert a command */ exit(1); } convert(buf, pin); - pclose(pin); + if (pclose(pin) != 0) + fprintf(stderr, + "%s: (%s): warning - bad status from \"%s\"\n", + progname, fname, buf); } else printf("\n%s\n", buf); } @@ -187,12 +198,13 @@ cvobject( /* convert an object */ FILE *fin ) { - extern char *fgetword(); char buf[128], typ[16], nam[128]; int i, n; - register int j; + int j; - if (fscanf(fin, "%s %s %s", buf, typ, nam) != 3) + 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++) @@ -200,11 +212,13 @@ cvobject( /* convert an object */ replace(fname, &marker[j], nam, fin); return; } - printf("\n%s %s %s\n", buf, typ, nam); + putchar('\n'); fputword(buf, stdout); + printf(" %s ", typ); + fputword(nam, stdout); putchar('\n'); if (!strcmp(typ, "alias")) { /* alias special case */ - if (fscanf(fin, "%s", buf) != 1) + if (fgetword(buf, sizeof(buf), fin) == NULL) goto readerr; - printf("\t%s\n", buf); + putchar('\t'); fputword(buf, stdout); putchar('\n'); return; } for (i = 0; i < 3; i++) { /* pass along arguments */ @@ -231,7 +245,7 @@ readerr: void replace( /* replace marker */ char *fname, - register struct mrkr *m, + struct mrkr *m, char *mark, FILE *fin ) @@ -240,8 +254,8 @@ replace( /* replace marker */ char buf[256]; buf[0] = '\0'; /* bug fix thanks to schorsch */ - if (m->doxform) { - sprintf(buf, "xform -e -n %s", mark); + 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) @@ -255,8 +269,10 @@ replace( /* replace marker */ } else { if ((n = buildxf(buf, m->mscale, fin)) < 0) goto badxf; - printf("\n%s instance %s\n", - m->modout==NULL?"void":m->modout, mark); + 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; @@ -283,7 +299,7 @@ edgecmp( /* compare two edges, descending order */ int buildxf( /* build transform for marker */ - register char *xf, + char *xf, double markscale, FILE *fin ) @@ -293,7 +309,7 @@ buildxf( /* build transform for marker */ FVECT xvec, yvec, zvec; double xlen; int n; - register int i; + int i; /* * Read and sort vectors: longest is hypotenuse, * second longest is x' axis, @@ -366,7 +382,7 @@ buildxf( /* build transform for marker */ int addrot( /* compute rotation (x,y,z) => (xp,yp,zp) */ - register char *xf, + char *xf, FVECT xp, FVECT yp, FVECT zp @@ -375,21 +391,29 @@ addrot( /* compute rotation (x,y,z) => (xp,yp,zp) */ 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)) { + if (!FABSEQ(theta,0.0)) { sprintf(xf, " -rx %f", theta*(180./PI)); while (*xf) ++xf; n += 2; } - theta = asin(-xp[2]); - if (!FEQ(theta,0.0)) { + theta = Asin(-xp[2]); + if (!FABSEQ(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)) { + if (!FABSEQ(theta,0.0)) { sprintf(xf, " -rz %f", theta*(180./PI)); /* while (*xf) ++xf; */ n += 2;