--- ray/src/cv/ies2rad.c 1995/04/25 21:37:14 2.12 +++ ray/src/cv/ies2rad.c 2003/11/15 13:29:23 2.23 @@ -1,18 +1,21 @@ -/* Copyright (c) 1992 Regents of the University of California */ - #ifndef lint -static char SCCSid[] = "$SunId$ LBL"; +static const char RCSid[] = "$Id: ies2rad.c,v 2.23 2003/11/15 13:29:23 schorsch Exp $"; #endif - /* * Convert IES luminaire data to Radiance description * * 07Apr90 Greg Ward + * + * Fixed correction factor for flat sources 29Oct2001 GW */ #include +#include #include +#include #include + +#include "rtio.h" #include "color.h" #include "paths.h" @@ -78,7 +81,7 @@ int filerev = FIRSTREV; #define U_METERS 2 /* string lengths */ #define MAXLINE 132 -#define MAXWORD 76 +#define RMAXWORD 76 /* file types */ #define T_RAD ".rad" #define T_DST ".dat" @@ -108,6 +111,7 @@ float defcolor[3] = {1.,1.,1.}; /* default lamp color float *lampcolor = defcolor; /* pointer to current lamp color */ double multiplier = 1.0; /* multiplier for all light sources */ char units[64] = "meters"; /* output units */ +int out2stdout = 0; /* put out to stdout r.t. file */ int instantiate = 0; /* instantiate geometry */ double illumrad = 0.0; /* radius for illum sphere */ @@ -122,23 +126,49 @@ typedef struct { int gargc; /* global argc (minus filenames) */ char **gargv; /* global argv */ -extern char *strcpy(), *strcat(), *stradd(), *tailtrunc(), *filetrunc(), - *filename(), *libname(), *fullname(), *malloc(), - *getword(), *atos(); -extern float *matchlamp(); #define scnint(fp,ip) cvtint(ip,getword(fp)) #define scnflt(fp,rp) cvtflt(rp,getword(fp)) #define isint isflt /* IES allows real as integer */ -main(argc, argv) -int argc; -char *argv[]; +static int ies2rad(char *inpname, char *outname); +static void initlamps(void); +static int dosource(SRCINFO *sinf, FILE *in, FILE *out, char *mod, char *name); +static int dotilt(FILE *in, FILE *out, char *dir, char *tltspec, + char *dfltname, char *tltid); +static int cvgeometry(char *inpname, SRCINFO *sinf, char *outname, FILE *outfp); +static int cvtint(int *ip, char *wrd); +static int cvdata(FILE *in, FILE *out, int ndim, int npts[], double mult, + double lim[][2]); +static int cvtflt(double *rp, char *wrd); +static int makeshape(SRCINFO *shp, double width, double length, double height); +static int putsource(SRCINFO *shp, FILE *fp, char *mod, char *name, + int dolower, int doupper, int dosides); +static void putrectsrc(SRCINFO *shp, FILE *fp, char *mod, char *name, int up); +static void putsides(SRCINFO *shp, FILE *fp, char *mod, char *name); +static void putdisksrc(SRCINFO *shp, FILE *fp, char *mod, char *name, int up); +static void putspheresrc(SRCINFO *shp, FILE *fp, char *mod, char *name); +static void putrect(SRCINFO *shp, FILE *fp, char *mod, char *name, char *suffix, + int a, int b, int c, int d); +static void putpoint(SRCINFO *shp, FILE *fp, int p); +static void putcyl(SRCINFO *shp, FILE *fp, char *mod, char *name); +static char * tailtrunc(char *name); +static char * filename(char *path); +static char * libname(char *path, char *fname, char *suffix); +static char * getword(FILE *fp); +static char * fullnam(char *path, char *fname, char *suffix); + + +int +main( + int argc, + char *argv[] +) { char *outfile = NULL; int status; - char outname[MAXWORD]; + char outname[RMAXWORD]; double d1; int i; @@ -203,9 +233,12 @@ char *argv[]; case 'f': /* lamp data file */ lampdat = argv[++i]; break; - case 'o': /* output file name */ + case 'o': /* output file root name */ outfile = argv[++i]; break; + case 's': /* output to stdout */ + out2stdout = !out2stdout; + break; case 'i': /* illum */ illumrad = atof(argv[++i]); break; @@ -241,16 +274,15 @@ char *argv[]; exit(ies2rad(NULL, outfile) == 0 ? 0 : 1); else if (i == argc-1) exit(ies2rad(argv[i], outfile) == 0 ? 0 : 1); - else { - fprintf(stderr, "%s: single input file required\n", - argv[0]); - exit(1); - } + else + goto needsingle; } else if (i >= argc) { fprintf(stderr, "%s: missing output file specification\n", argv[0]); exit(1); } + if (out2stdout && i != argc-1) + goto needsingle; status = 0; for ( ; i < argc; i++) { tailtrunc(strcpy(outname,filename(argv[i]))); @@ -258,10 +290,13 @@ char *argv[]; status = 1; } exit(status); +needsingle: + fprintf(stderr, "%s: single input file required\n", argv[0]); + exit(1); } - -initlamps() /* set up lamps */ +void +initlamps(void) /* set up lamps */ { float *lcol; int status; @@ -302,9 +337,11 @@ initlamps() /* set up lamps */ char * -stradd(dst, src, sep) /* add a string at dst */ -register char *dst, *src; -int sep; +stradd( /* add a string at dst */ + register char *dst, + register char *src, + int sep +) { if (src && *src) { do @@ -319,8 +356,11 @@ int sep; char * -fullname(path, fname, suffix) /* return full path name */ -char *path, *fname, *suffix; +fullnam( /* return full path name */ + char *path, + char *fname, + char *suffix +) { if (prefdir != NULL && abspath(prefdir)) libname(path, fname, suffix); @@ -334,8 +374,11 @@ char *path, *fname, *suffix; char * -libname(path, fname, suffix) /* return library relative name */ -char *path, *fname, *suffix; +libname( /* return library relative name */ + char *path, + char *fname, + char *suffix +) { if (abspath(fname)) strcpy(stradd(path, fname, 0), suffix); @@ -347,8 +390,9 @@ char *path, *fname, *suffix; char * -filename(path) /* get final component of pathname */ -register char *path; +filename( /* get final component of pathname */ + register char *path +) { register char *cp; @@ -360,8 +404,9 @@ register char *path; char * -filetrunc(path) /* truncate filename at end of path */ -char *path; +filetrunc( /* truncate filename at end of path */ + char *path +) { register char *p1, *p2; @@ -376,8 +421,9 @@ char *path; char * -tailtrunc(name) /* truncate tail of filename */ -char *name; +tailtrunc( /* truncate tail of filename */ + char *name +) { register char *p1, *p2; @@ -393,8 +439,10 @@ char *name; } -blanktrunc(s) /* truncate spaces at end of line */ -char *s; +void +blanktrunc( /* truncate spaces at end of line */ + char *s +) { register char *cp; @@ -406,21 +454,25 @@ char *s; } -k_match(kwd, hdl) /* header line matches keyword? */ -register char *kwd, *hdl; +int +k_match( /* header line matches keyword? */ + register char *kwd, + register char *hdl +) { if (!*hdl++ == '[') return(0); while (islower(*hdl) ? toupper(*hdl) == *kwd++ : *hdl == *kwd++) if (!*hdl++) return(0); - return(!*kwd & *hdl == ']'); + return((!*kwd) & (*hdl == ']')); } char * -keyargs(hdl) /* return keyword arguments */ -register char *hdl; +keyargs( /* return keyword arguments */ + register char *hdl +) { while (*hdl && *hdl++ != ']') ; @@ -430,8 +482,10 @@ register char *hdl; } -putheader(out) /* print header */ -FILE *out; +void +putheader( /* print header */ + FILE *out +) { register int i; @@ -446,11 +500,14 @@ FILE *out; } -ies2rad(inpname, outname) /* convert IES file */ -char *inpname, *outname; +int +ies2rad( /* convert IES file */ + char *inpname, + char *outname +) { SRCINFO srcinfo; - char buf[MAXLINE], tltid[MAXWORD]; + char buf[MAXLINE], tltid[RMAXWORD]; char geomfile[128]; FILE *inpfp, *outfp; int lineno = 0; @@ -464,7 +521,9 @@ char *inpname, *outname; perror(inpname); return(-1); } - if ((outfp = fopen(fullname(buf,outname,T_RAD), "w")) == NULL) { + if (out2stdout) + outfp = stdout; + else if ((outfp = fopen(fullnam(buf,outname,T_RAD), "w")) == NULL) { perror(buf); fclose(inpfp); return(-1); @@ -507,7 +566,7 @@ char *inpname, *outname; fprintf(stderr, "%s: not in IES format\n", inpname); goto readerr; } - atos(tltid, MAXWORD, buf+TLTSTRLEN); + atos(tltid, RMAXWORD, buf+TLTSTRLEN); if (inpfp == stdin) buf[0] = '\0'; else @@ -530,18 +589,24 @@ char *inpname, *outname; readerr: fclose(inpfp); fclose(outfp); - unlink(fullname(buf,outname,T_RAD)); + unlink(fullnam(buf,outname,T_RAD)); return(-1); } -dotilt(in, out, dir, tltspec, dfltname, tltid) /* convert tilt data */ -FILE *in, *out; -char *dir, *tltspec, *dfltname, *tltid; +int +dotilt( /* convert tilt data */ + FILE *in, + FILE *out, + char *dir, + char *tltspec, + char *dfltname, + char *tltid +) { int nangles, tlt_type; - double minmax[2]; - char buf[MAXPATH], tltname[MAXWORD]; + double minmax[1][2]; + char buf[PATH_MAX], tltname[RMAXWORD]; FILE *datin, *datout; if (!strcmp(tltspec, TLTNONE)) { @@ -562,7 +627,7 @@ char *dir, *tltspec, *dfltname, *tltid; tailtrunc(strcpy(tltname,filename(tltspec))); } if (datin != NULL) { - if ((datout = fopen(fullname(buf,tltname,T_TLT),"w")) == NULL) { + if ((datout = fopen(fullnam(buf,tltname,T_TLT),"w")) == NULL) { perror(buf); if (datin != in) fclose(datin); @@ -574,7 +639,7 @@ char *dir, *tltspec, *dfltname, *tltid; fclose(datout); if (datin != in) fclose(datin); - unlink(fullname(buf,tltname,T_TLT)); + unlink(fullnam(buf,tltname,T_TLT)); return(-1); } fclose(datout); @@ -586,15 +651,15 @@ char *dir, *tltspec, *dfltname, *tltid; switch (tlt_type) { case TLT_VERT: /* vertical */ fprintf(out, "4 noop %s tilt.cal %s\n", buf, - minmax[1]>90.+FTINY ? "tilt_ang" : "tilt_ang2"); + minmax[0][1]>90.+FTINY ? "tilt_ang" : "tilt_ang2"); break; case TLT_H0: /* horiz. in 0 deg. plane */ fprintf(out, "6 noop %s tilt.cal %s -rz 90\n", buf, - minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2"); + minmax[0][1]>90.+FTINY ? "tilt_xang" : "tilt_xang2"); break; case TLT_H90: fprintf(out, "4 noop %s tilt.cal %s\n", buf, - minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2"); + minmax[0][1]>90.+FTINY ? "tilt_xang" : "tilt_xang2"); break; default: fprintf(stderr, @@ -608,17 +673,22 @@ char *dir, *tltspec, *dfltname, *tltid; } -dosource(sinf, in, out, mod, name) /* create source and distribution */ -SRCINFO *sinf; -FILE *in, *out; -char *mod, *name; +int +dosource( /* create source and distribution */ + SRCINFO *sinf, + FILE *in, + FILE *out, + char *mod, + char *name +) { - char buf[MAXPATH], id[MAXWORD]; + char buf[PATH_MAX], id[RMAXWORD]; FILE *datout; double mult, bfactor, pfactor, width, length, height, wattage; double bounds[2][2]; int nangles[2], pmtype, unitype; double d1; + int doupper, dolower, dosides; if (!isint(getword(in)) || !isflt(getword(in)) || !scnflt(in,&mult) || !scnint(in,&nangles[0]) || !scnint(in,&nangles[1]) @@ -643,14 +713,14 @@ char *mod, *name; fprintf(stderr, "dosource: illegal source dimensions"); return(-1); } - if ((datout = fopen(fullname(buf,name,T_DST), "w")) == NULL) { + if ((datout = fopen(fullnam(buf,name,T_DST), "w")) == NULL) { perror(buf); return(-1); } if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, bounds) != 0) { fprintf(stderr, "dosource: bad distribution data\n"); fclose(datout); - unlink(fullname(buf,name,T_DST)); + unlink(fullnam(buf,name,T_DST)); return(-1); } fclose(datout); @@ -666,8 +736,13 @@ char *mod, *name; fprintf(out, "7 "); else fprintf(out, "5 "); + dolower = (bounds[0][0] < 90.); + doupper = (bounds[0][1] > 90.); + dosides = (doupper & dolower && sinf->h > MINDIM); fprintf(out, "%s %s source.cal ", - sinf->type==SPHERE ? "corr" : "flatcorr", + sinf->type==SPHERE ? "corr" : + !dosides ? "flatcorr" : + sinf->type==DISK ? "cylcorr" : "boxcorr", libname(buf,name,T_DST)); if (pmtype == PM_B) { if (FEQ(bounds[1][0],0.)) @@ -675,14 +750,17 @@ char *mod, *name; else fprintf(out, "srcB_horiz "); fprintf(out, "srcB_vert "); - } else { + } else /* pmtype == PM_A */ { if (nangles[1] >= 2) { d1 = bounds[1][1] - bounds[1][0]; if (d1 <= 90.+FTINY) fprintf(out, "src_phi4 "); - else if (d1 <= 180.+FTINY) - fprintf(out, "src_phi2 "); - else + else if (d1 <= 180.+FTINY) { + if (FEQ(bounds[1][0],90.)) + fprintf(out, "src_phi2+90 "); + else + fprintf(out, "src_phi2 "); + } else fprintf(out, "src_phi "); fprintf(out, "src_theta "); if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.)) @@ -690,75 +768,71 @@ char *mod, *name; } else fprintf(out, "src_theta "); } - fprintf(out, "\n0\n1 %g\n", sinf->mult); + if (!dosides || sinf->type == SPHERE) + fprintf(out, "\n0\n1 %g\n", sinf->mult/sinf->area); + else if (sinf->type == DISK) + fprintf(out, "\n0\n3 %g %g %g\n", sinf->mult, + sinf->w, sinf->h); + else + fprintf(out, "\n0\n4 %g %g %g %g\n", sinf->mult, + sinf->l, sinf->w, sinf->h); if (putsource(sinf, out, id, filename(name), - bounds[0][0]<90., bounds[0][1]>90.) != 0) + dolower, doupper, dosides) != 0) return(-1); return(0); } -putsource(shp, fp, mod, name, dolower, doupper) /* put out source */ -SRCINFO *shp; -FILE *fp; -char *mod, *name; -int dolower, doupper; +int +putsource( /* put out source */ + SRCINFO *shp, + FILE *fp, + char *mod, + char *name, + int dolower, + int doupper, + int dosides +) { - char buf[MAXWORD]; + char lname[RMAXWORD]; - fprintf(fp, "\n%s %s %s_light\n", mod, - shp->isillum ? "illum" : "light", - name); + strcat(strcpy(lname, name), "_light"); + fprintf(fp, "\n%s %s %s\n", mod, + shp->isillum ? "illum" : "light", lname); fprintf(fp, "0\n0\n3 %g %g %g\n", - lampcolor[0]/shp->area, - lampcolor[1]/shp->area, - lampcolor[2]/shp->area); - if (doupper && dolower && shp->type != SPHERE && shp->h > MINDIM) - if (shp->isillum) { - fprintf(fp, "\nvoid illum %s_glow\n", name); - fprintf(fp, "0\n0\n3 0 0 0\n"); - } else { - fprintf(fp, "\n%s glow %s_glow\n", mod, name); - fprintf(fp, "0\n0\n4 %g %g %g -1\n", - lampcolor[0]/shp->area, - lampcolor[1]/shp->area, - lampcolor[2]/shp->area); - } + lampcolor[0], lampcolor[1], lampcolor[2]); switch (shp->type) { case RECT: - strcat(strcpy(buf, name), "_light"); if (dolower) - putrectsrc(shp, fp, buf, name, 0); + putrectsrc(shp, fp, lname, name, 0); if (doupper) - putrectsrc(shp, fp, buf, name, 1); - if (doupper && dolower && shp->h > MINDIM) { - strcat(strcpy(buf, name), "_glow"); - putsides(shp, fp, buf, name); - } + putrectsrc(shp, fp, lname, name, 1); + if (dosides) + putsides(shp, fp, lname, name); break; case DISK: - strcat(strcpy(buf, name), "_light"); if (dolower) - putdisksrc(shp, fp, buf, name, 0); + putdisksrc(shp, fp, lname, name, 0); if (doupper) - putdisksrc(shp, fp, buf, name, 1); - if (doupper && dolower && shp->h > MINDIM) { - strcat(strcpy(buf, name), "_glow"); - putcyl(shp, fp, buf, name); - } + putdisksrc(shp, fp, lname, name, 1); + if (dosides) + putcyl(shp, fp, lname, name); break; case SPHERE: - strcat(strcpy(buf, name), "_light"); - putspheresrc(shp, fp, buf, name); + putspheresrc(shp, fp, lname, name); break; } return(0); } -makeshape(shp, width, length, height) /* make source shape */ -register SRCINFO *shp; -double width, length, height; +int +makeshape( /* make source shape */ + register SRCINFO *shp, + double width, + double length, + double height +) { if (illumrad/meters2out >= MINDIM/2.) { shp->isillum = 1; @@ -805,11 +879,14 @@ double width, length, height; } -putrectsrc(shp, fp, mod, name, up) /* rectangular source */ -SRCINFO *shp; -FILE *fp; -char *mod, *name; -int up; +void +putrectsrc( /* rectangular source */ + SRCINFO *shp, + FILE *fp, + char *mod, + char *name, + int up +) { if (up) putrect(shp, fp, mod, name, ".u", 4, 5, 7, 6); @@ -818,10 +895,13 @@ int up; } -putsides(shp, fp, mod, name) /* put out sides of box */ -register SRCINFO *shp; -FILE *fp; -char *mod, *name; +void +putsides( /* put out sides of box */ + register SRCINFO *shp, + FILE *fp, + char *mod, + char *name +) { putrect(shp, fp, mod, name, ".1", 0, 1, 5, 4); putrect(shp, fp, mod, name, ".2", 1, 3, 7, 5); @@ -830,11 +910,18 @@ char *mod, *name; } -putrect(shp, fp, mod, name, suffix, a, b, c, d) /* put out a rectangle */ -SRCINFO *shp; -FILE *fp; -char *mod, *name, *suffix; -int a, b, c, d; +void +putrect( /* put out a rectangle */ + SRCINFO *shp, + FILE *fp, + char *mod, + char *name, + char *suffix, + int a, + int b, + int c, + int d +) { fprintf(fp, "\n%s polygon %s%s\n0\n0\n12\n", mod, name, suffix); putpoint(shp, fp, a); @@ -844,10 +931,12 @@ int a, b, c, d; } -putpoint(shp, fp, p) /* put out a point */ -register SRCINFO *shp; -FILE *fp; -int p; +void +putpoint( /* put out a point */ + register SRCINFO *shp, + FILE *fp, + int p +) { static double mult[2] = {-.5, .5}; @@ -858,11 +947,14 @@ int p; } -putdisksrc(shp, fp, mod, name, up) /* put out a disk source */ -register SRCINFO *shp; -FILE *fp; -char *mod, *name; -int up; +void +putdisksrc( /* put out a disk source */ + register SRCINFO *shp, + FILE *fp, + char *mod, + char *name, + int up +) { if (up) { fprintf(fp, "\n%s ring %s.u\n", mod, name); @@ -880,10 +972,13 @@ int up; } -putcyl(shp, fp, mod, name) /* put out a cylinder */ -register SRCINFO *shp; -FILE *fp; -char *mod, *name; +void +putcyl( /* put out a cylinder */ + register SRCINFO *shp, + FILE *fp, + char *mod, + char *name +) { fprintf(fp, "\n%s cylinder %s.c\n", mod, name); fprintf(fp, "0\n0\n7\n"); @@ -893,20 +988,28 @@ char *mod, *name; } -putspheresrc(shp, fp, mod, name) /* put out a sphere source */ -SRCINFO *shp; -FILE *fp; -char *mod, *name; +void +putspheresrc( /* put out a sphere source */ + SRCINFO *shp, + FILE *fp, + char *mod, + char *name +) { fprintf(fp, "\n%s sphere %s.s\n", mod, name); fprintf(fp, "0\n0\n4 0 0 0 %g\n", .5*shp->w*meters2out); } -cvdata(in, out, ndim, npts, mult, lim) /* convert data */ -FILE *in, *out; -int ndim, npts[]; -double mult, lim[][2]; +int +cvdata( /* convert data */ + FILE *in, + FILE *out, + int ndim, + int npts[], + double mult, + double lim[][2] +) { double *pt[4]; register int i, j; @@ -951,7 +1054,7 @@ double mult, lim[][2]; putc('\n', out); } } - free((char *)pt[i]); + free((void *)pt[i]); } for (i = 0; i < total; i++) { if (i%4 == 0) @@ -966,57 +1069,64 @@ double mult, lim[][2]; char * -getword(fp) /* scan a word from fp */ -register FILE *fp; +getword( /* scan a word from fp */ + register FILE *fp +) { - static char word[MAXWORD]; + static char wrd[RMAXWORD]; register char *cp; register int c; while (isspace(c=getc(fp))) ; - for (cp = word; c != EOF && cp < word+MAXWORD-1; + for (cp = wrd; c != EOF && cp < wrd+RMAXWORD-1; *cp++ = c, c = getc(fp)) if (isspace(c) || c == ',') { while (isspace(c)) c = getc(fp); - if (c != EOF & c != ',') + if ((c != EOF) & (c != ',')) ungetc(c, fp); *cp = '\0'; - return(word); + return(wrd); } *cp = '\0'; - return(cp > word ? word : NULL); + return(cp > wrd ? wrd : NULL); } -cvtint(ip, word) /* convert a word to an integer */ -int *ip; -char *word; +int +cvtint( /* convert a word to an integer */ + int *ip, + char *wrd +) { - if (word == NULL || !isint(word)) + if (wrd == NULL || !isint(wrd)) return(0); - *ip = atoi(word); + *ip = atoi(wrd); return(1); } -cvtflt(rp, word) /* convert a word to a double */ -double *rp; -char *word; +int +cvtflt( /* convert a word to a double */ + double *rp, + char *wrd +) { - if (word == NULL || !isflt(word)) + if (wrd == NULL || !isflt(wrd)) return(0); - *rp = atof(word); + *rp = atof(wrd); return(1); } -cvgeometry(inpname, sinf, outname, outfp) -char *inpname; -register SRCINFO *sinf; -char *outname; -FILE *outfp; /* close output file upon return */ +int +cvgeometry( + char *inpname, + register SRCINFO *sinf, + char *outname, + FILE *outfp /* close output file upon return */ +) { char buf[256]; register char *cp; @@ -1039,8 +1149,9 @@ FILE *outfp; /* close output file upon return */ if (instantiate) { /* instantiate octree */ strcpy(cp, "| oconv - > "); cp += 12; - fullname(cp,outname,T_OCT); - if (system(buf)) { /* create octree */ + fullnam(cp,outname,T_OCT); + if (fdate(inpname) > fdate(outname) && + system(buf)) { /* create octree */ fclose(outfp); return(-1); } @@ -1054,14 +1165,16 @@ FILE *outfp; /* close output file upon return */ fprintf(outfp, "0\n0\n"); fclose(outfp); } else { /* else append to luminaire file */ - fclose(outfp); if (!FEQ(meters2out, 1.0)) { /* apply scalefactor */ sprintf(cp, "| xform -s %f ", meters2out); cp += strlen(cp); } - strcpy(cp, ">> "); /* append works for DOS? */ - cp += 3; - fullname(cp,outname,T_RAD); + if (!out2stdout) { + fclose(outfp); + strcpy(cp, ">> "); /* append works for DOS? */ + cp += 3; + fullnam(cp,outname,T_RAD); + } if (system(buf)) return(-1); }