ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.19
Committed: Mon Jun 30 14:59:11 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.18: +3 -3 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.19 static const char RCSid[] = "$Id: ies2rad.c,v 2.18 2003/02/22 02:07:23 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * Convert IES luminaire data to Radiance description
6     *
7     * 07Apr90 Greg Ward
8 greg 2.18 *
9     * Fixed correction factor for flat sources 29Oct2001 GW
10 greg 1.1 */
11    
12     #include <stdio.h>
13 greg 2.8 #include <math.h>
14 greg 2.14 #include <sys/types.h>
15 greg 1.1 #include <ctype.h>
16 greg 1.2 #include "color.h"
17 greg 2.4 #include "paths.h"
18 greg 1.1
19     #define PI 3.14159265358979323846
20     /* floating comparisons */
21     #define FTINY 1e-6
22     #define FEQ(a,b) ((a)<=(b)+FTINY&&(a)>=(b)-FTINY)
23 greg 2.12 /* keywords */
24     #define MAGICID "IESNA"
25     #define LMAGICID 5
26     #define FIRSTREV 86
27     #define LASTREV 95
28    
29     #define D86 0 /* keywords defined in LM-63-1986 */
30    
31     #define K_TST 0
32     #define K_MAN 1
33     #define K_LMC 2
34     #define K_LMN 3
35     #define K_LPC 4
36     #define K_LMP 5
37     #define K_BAL 6
38     #define K_MTC 7
39     #define K_OTH 8
40     #define K_SCH 9
41     #define K_MOR 10
42     #define K_BLK 11
43     #define K_EBK 12
44    
45     #define D91 ((1L<<13)-1) /* keywords defined in LM-63-1991 */
46    
47     #define K_LMG 13
48    
49     #define D95 ((1L<<14)-1) /* keywords defined in LM-63-1995 */
50    
51     char k_kwd[][20] = {"TEST", "MANUFAC", "LUMCAT", "LUMINAIRE", "LAMPCAT",
52     "LAMP", "BALLAST", "MAINTCAT", "OTHER", "SEARCH",
53     "MORE", "BLOCK", "ENDBLOCK", "LUMINOUSGEOMETRY"};
54    
55     long k_defined[] = {D86, D86, D86, D86, D86, D91, D91, D91, D91, D95};
56    
57     int filerev = FIRSTREV;
58    
59     #define keymatch(i,s) (k_defined[filerev-FIRSTREV]&1L<<(i) &&\
60     k_match(k_kwd[i],s))
61    
62     #define checklamp(s) (!(k_defined[filerev-FIRSTREV]&(1<<K_LMP|1<<K_LPC)) ||\
63     keymatch(K_LMP,s) || keymatch(K_LPC,s))
64    
65 greg 1.1 /* tilt specs */
66     #define TLTSTR "TILT="
67     #define TLTSTRLEN 5
68     #define TLTNONE "NONE"
69     #define TLTINCL "INCLUDE"
70     #define TLT_VERT 1
71     #define TLT_H0 2
72     #define TLT_H90 3
73     /* photometric types */
74     #define PM_C 1
75     #define PM_B 2
76     /* unit types */
77     #define U_FEET 1
78     #define U_METERS 2
79     /* string lengths */
80     #define MAXLINE 132
81     #define MAXWORD 76
82     /* file types */
83     #define T_RAD ".rad"
84     #define T_DST ".dat"
85 greg 2.10 #define T_TLT "%.dat"
86 greg 2.12 #define T_OCT ".oct"
87 greg 1.1 /* shape types */
88     #define RECT 1
89     #define DISK 2
90     #define SPHERE 3
91    
92     #define MINDIM .001 /* minimum dimension (point source) */
93    
94     #define F_M .3048 /* feet to meters */
95    
96 greg 2.4 #define abspath(p) (ISDIRSEP((p)[0]) || (p)[0] == '.')
97 greg 1.1
98 greg 1.2 static char default_name[] = "default";
99    
100 greg 1.1 char *libdir = NULL; /* library directory location */
101     char *prefdir = NULL; /* subdirectory */
102     char *lampdat = "lamp.tab"; /* lamp data file */
103    
104     double meters2out = 1.0; /* conversion from meters to output */
105     char *lamptype = NULL; /* selected lamp type */
106 greg 1.2 char *deflamp = NULL; /* default lamp type */
107 greg 1.1 float defcolor[3] = {1.,1.,1.}; /* default lamp color */
108 greg 1.2 float *lampcolor = defcolor; /* pointer to current lamp color */
109 greg 1.1 double multiplier = 1.0; /* multiplier for all light sources */
110     char units[64] = "meters"; /* output units */
111 greg 2.13 int out2stdout = 0; /* put out to stdout r.t. file */
112 greg 2.12 int instantiate = 0; /* instantiate geometry */
113 greg 1.1 double illumrad = 0.0; /* radius for illum sphere */
114    
115     typedef struct {
116 greg 2.12 int isillum; /* do as illum */
117 greg 1.1 int type; /* RECT, DISK, SPHERE */
118 greg 2.12 double mult; /* candela multiplier */
119 greg 1.1 double w, l, h; /* width, length, height */
120 greg 1.3 double area; /* max. projected area */
121 greg 2.12 } SRCINFO; /* a source shape (units=meters) */
122 greg 1.1
123     int gargc; /* global argc (minus filenames) */
124     char **gargv; /* global argv */
125    
126     extern char *strcpy(), *strcat(), *stradd(), *tailtrunc(), *filetrunc(),
127 greg 2.18 *filename(), *libname(), *fullnam(), *getword(), *atos();
128 greg 1.1 extern float *matchlamp();
129 greg 2.14 extern time_t fdate();
130 greg 1.1
131 greg 2.6 #define scnint(fp,ip) cvtint(ip,getword(fp))
132     #define scnflt(fp,rp) cvtflt(rp,getword(fp))
133     #define isint isflt /* IES allows real as integer */
134 greg 1.1
135 greg 2.6
136 greg 1.1 main(argc, argv)
137     int argc;
138     char *argv[];
139     {
140     char *outfile = NULL;
141     int status;
142     char outname[MAXWORD];
143     double d1;
144     int i;
145    
146     for (i = 1; i < argc && argv[i][0] == '-'; i++)
147     switch (argv[i][1]) {
148     case 'd': /* dimensions */
149     if (argv[i][2] == '\0')
150     goto badopt;
151     if (argv[i][3] == '\0')
152     d1 = 1.0;
153     else if (argv[i][3] == '/') {
154     d1 = atof(argv[i]+4);
155     if (d1 <= FTINY)
156     goto badopt;
157     } else
158     goto badopt;
159     switch (argv[i][2]) {
160     case 'c': /* centimeters */
161     if (FEQ(d1,10.))
162     strcpy(units,"millimeters");
163     else {
164     strcpy(units,"centimeters");
165     strcat(units,argv[i]+3);
166     }
167     meters2out = 100.*d1;
168     break;
169     case 'm': /* meters */
170     if (FEQ(d1,1000.))
171     strcpy(units,"millimeters");
172     else if (FEQ(d1,100.))
173     strcpy(units,"centimeters");
174     else {
175     strcpy(units,"meters");
176     strcat(units,argv[i]+3);
177     }
178     meters2out = d1;
179     break;
180     case 'i': /* inches */
181     strcpy(units,"inches");
182     strcat(units,argv[i]+3);
183     meters2out = d1*(12./F_M);
184     break;
185     case 'f': /* feet */
186     if (FEQ(d1,12.))
187     strcpy(units,"inches");
188     else {
189     strcpy(units,"feet");
190     strcat(units,argv[i]+3);
191     }
192     meters2out = d1/F_M;
193     break;
194     default:
195     goto badopt;
196     }
197     break;
198     case 'l': /* library directory */
199     libdir = argv[++i];
200     break;
201     case 'p': /* prefix subdirectory */
202     prefdir = argv[++i];
203     break;
204     case 'f': /* lamp data file */
205     lampdat = argv[++i];
206     break;
207 greg 2.13 case 'o': /* output file root name */
208 greg 1.1 outfile = argv[++i];
209     break;
210 greg 2.13 case 's': /* output to stdout */
211     out2stdout = !out2stdout;
212     break;
213 greg 1.1 case 'i': /* illum */
214     illumrad = atof(argv[++i]);
215     break;
216 greg 2.12 case 'g': /* instatiate geometry? */
217     instantiate = !instantiate;
218     break;
219 greg 1.2 case 't': /* override lamp type */
220 greg 1.1 lamptype = argv[++i];
221     break;
222 greg 1.2 case 'u': /* default lamp type */
223     deflamp = argv[++i];
224     break;
225 greg 1.1 case 'c': /* default lamp color */
226     defcolor[0] = atof(argv[++i]);
227     defcolor[1] = atof(argv[++i]);
228     defcolor[2] = atof(argv[++i]);
229     break;
230     case 'm': /* multiplier */
231     multiplier = atof(argv[++i]);
232     break;
233     default:
234     badopt:
235     fprintf(stderr, "%s: bad option: %s\n",
236     argv[0], argv[i]);
237     exit(1);
238     }
239     gargc = i;
240     gargv = argv;
241 greg 1.2 initlamps(); /* get lamp data (if needed) */
242 greg 1.1 /* convert ies file(s) */
243     if (outfile != NULL) {
244     if (i == argc)
245     exit(ies2rad(NULL, outfile) == 0 ? 0 : 1);
246     else if (i == argc-1)
247     exit(ies2rad(argv[i], outfile) == 0 ? 0 : 1);
248 greg 2.13 else
249     goto needsingle;
250 greg 1.1 } else if (i >= argc) {
251     fprintf(stderr, "%s: missing output file specification\n",
252     argv[0]);
253     exit(1);
254     }
255 greg 2.13 if (out2stdout && i != argc-1)
256     goto needsingle;
257 greg 1.1 status = 0;
258     for ( ; i < argc; i++) {
259     tailtrunc(strcpy(outname,filename(argv[i])));
260     if (ies2rad(argv[i], outname) != 0)
261     status = 1;
262     }
263     exit(status);
264 greg 2.13 needsingle:
265     fprintf(stderr, "%s: single input file required\n", argv[0]);
266     exit(1);
267 greg 1.2 }
268    
269    
270     initlamps() /* set up lamps */
271     {
272     float *lcol;
273     int status;
274    
275     if (lamptype != NULL && !strcmp(lamptype, default_name) &&
276     deflamp == NULL)
277     return; /* no need for data */
278     /* else load file */
279     if ((status = loadlamps(lampdat)) < 0)
280     exit(1);
281     if (status == 0) {
282     fprintf(stderr, "%s: warning - no lamp data\n", lampdat);
283     lamptype = default_name;
284     return;
285     }
286     if (deflamp != NULL) { /* match default type */
287     if ((lcol = matchlamp(deflamp)) == NULL)
288     fprintf(stderr,
289     "%s: warning - unknown default lamp type\n",
290     deflamp);
291     else
292     copycolor(defcolor, lcol);
293     }
294     if (lamptype != NULL) { /* match selected type */
295     if (strcmp(lamptype, default_name)) {
296     if ((lcol = matchlamp(lamptype)) == NULL) {
297     fprintf(stderr,
298     "%s: warning - unknown lamp type\n",
299     lamptype);
300     lamptype = default_name;
301     } else
302     copycolor(defcolor, lcol);
303     }
304     freelamps(); /* all done with data */
305     }
306     /* else keep lamp data */
307 greg 1.1 }
308    
309    
310     char *
311     stradd(dst, src, sep) /* add a string at dst */
312     register char *dst, *src;
313     int sep;
314     {
315     if (src && *src) {
316     do
317     *dst++ = *src++;
318     while (*src);
319     if (sep && dst[-1] != sep)
320     *dst++ = sep;
321     }
322     *dst = '\0';
323     return(dst);
324     }
325    
326    
327     char *
328 greg 2.18 fullnam(path, fname, suffix) /* return full path name */
329 greg 1.1 char *path, *fname, *suffix;
330     {
331     if (prefdir != NULL && abspath(prefdir))
332     libname(path, fname, suffix);
333     else if (abspath(fname))
334     strcpy(stradd(path, fname, 0), suffix);
335     else
336 greg 2.4 libname(stradd(path, libdir, DIRSEP), fname, suffix);
337 greg 1.1
338     return(path);
339     }
340    
341    
342     char *
343     libname(path, fname, suffix) /* return library relative name */
344     char *path, *fname, *suffix;
345     {
346     if (abspath(fname))
347     strcpy(stradd(path, fname, 0), suffix);
348     else
349 greg 2.4 strcpy(stradd(stradd(path, prefdir, DIRSEP), fname, 0), suffix);
350 greg 1.1
351     return(path);
352     }
353    
354    
355     char *
356     filename(path) /* get final component of pathname */
357     register char *path;
358     {
359     register char *cp;
360    
361     for (cp = path; *path; path++)
362 greg 2.4 if (ISDIRSEP(*path))
363 greg 1.1 cp = path+1;
364     return(cp);
365     }
366    
367    
368     char *
369     filetrunc(path) /* truncate filename at end of path */
370     char *path;
371     {
372     register char *p1, *p2;
373    
374     for (p1 = p2 = path; *p2; p2++)
375 greg 2.4 if (ISDIRSEP(*p2))
376 greg 1.1 p1 = p2;
377 greg 2.12 if (p1 == path && ISDIRSEP(*p1))
378     p1++;
379 greg 1.1 *p1 = '\0';
380     return(path);
381     }
382    
383    
384     char *
385     tailtrunc(name) /* truncate tail of filename */
386     char *name;
387     {
388     register char *p1, *p2;
389    
390     for (p1 = filename(name); *p1 == '.'; p1++)
391     ;
392     p2 = NULL;
393     for ( ; *p1; p1++)
394     if (*p1 == '.')
395     p2 = p1;
396     if (p2 != NULL)
397     *p2 = '\0';
398     return(name);
399     }
400    
401    
402     blanktrunc(s) /* truncate spaces at end of line */
403     char *s;
404     {
405     register char *cp;
406    
407     for (cp = s; *cp; cp++)
408     ;
409     while (cp-- > s && isspace(*cp))
410     ;
411     *++cp = '\0';
412     }
413    
414    
415 greg 2.12 k_match(kwd, hdl) /* header line matches keyword? */
416     register char *kwd, *hdl;
417     {
418     if (!*hdl++ == '[')
419     return(0);
420     while (islower(*hdl) ? toupper(*hdl) == *kwd++ : *hdl == *kwd++)
421     if (!*hdl++)
422     return(0);
423     return(!*kwd & *hdl == ']');
424     }
425    
426    
427     char *
428     keyargs(hdl) /* return keyword arguments */
429     register char *hdl;
430     {
431     while (*hdl && *hdl++ != ']')
432     ;
433     while (isspace(*hdl))
434     hdl++;
435     return(hdl);
436     }
437    
438    
439 greg 1.1 putheader(out) /* print header */
440     FILE *out;
441     {
442     register int i;
443    
444     putc('#', out);
445     for (i = 0; i < gargc; i++) {
446     putc(' ', out);
447     fputs(gargv[i], out);
448     }
449     fputs("\n# Dimensions in ", out);
450     fputs(units, out);
451     putc('\n', out);
452     }
453    
454    
455     ies2rad(inpname, outname) /* convert IES file */
456     char *inpname, *outname;
457     {
458 greg 2.12 SRCINFO srcinfo;
459 greg 1.1 char buf[MAXLINE], tltid[MAXWORD];
460 greg 2.12 char geomfile[128];
461 greg 1.1 FILE *inpfp, *outfp;
462 greg 2.12 int lineno = 0;
463 greg 1.1
464 greg 2.12 geomfile[0] = '\0';
465     srcinfo.isillum = 0;
466 greg 1.1 if (inpname == NULL) {
467     inpname = "<stdin>";
468     inpfp = stdin;
469     } else if ((inpfp = fopen(inpname, "r")) == NULL) {
470     perror(inpname);
471     return(-1);
472     }
473 greg 2.13 if (out2stdout)
474     outfp = stdout;
475 greg 2.18 else if ((outfp = fopen(fullnam(buf,outname,T_RAD), "w")) == NULL) {
476 greg 1.1 perror(buf);
477     fclose(inpfp);
478     return(-1);
479     }
480     putheader(outfp);
481     if (lamptype == NULL)
482     lampcolor = NULL;
483     while (fgets(buf,sizeof(buf),inpfp) != NULL
484     && strncmp(buf,TLTSTR,TLTSTRLEN)) {
485     blanktrunc(buf);
486     if (!buf[0])
487     continue;
488 greg 2.12 if (!lineno++ && !strncmp(buf, MAGICID, LMAGICID)) {
489     filerev = atoi(buf+LMAGICID);
490     if (filerev < FIRSTREV)
491     filerev = FIRSTREV;
492     else if (filerev > LASTREV)
493     filerev = LASTREV;
494     }
495 greg 1.1 fputs("#<", outfp);
496     fputs(buf, outfp);
497     putc('\n', outfp);
498 greg 2.12 if (lampcolor == NULL && checklamp(buf))
499     lampcolor = matchlamp( buf[0] == '[' ?
500     keyargs(buf) : buf );
501     if (keymatch(K_LMG, buf)) { /* geometry file */
502     strcpy(geomfile, inpname);
503     strcpy(filename(geomfile), keyargs(buf));
504     srcinfo.isillum = 1;
505     }
506 greg 1.1 }
507     if (lampcolor == NULL) {
508     fprintf(stderr, "%s: warning - no lamp type\n", inpname);
509 greg 2.9 fputs("# Unknown lamp type (used default)\n", outfp);
510 greg 1.1 lampcolor = defcolor;
511 greg 2.9 } else if (lamptype == NULL)
512     fprintf(outfp,"# CIE(x,y) = (%f,%f)\n# Depreciation = %.1f%%\n",
513     lampcolor[3], lampcolor[4], 100.*lampcolor[5]);
514 greg 1.1 if (feof(inpfp)) {
515     fprintf(stderr, "%s: not in IES format\n", inpname);
516     goto readerr;
517     }
518 greg 2.6 atos(tltid, MAXWORD, buf+TLTSTRLEN);
519 greg 1.1 if (inpfp == stdin)
520     buf[0] = '\0';
521     else
522     filetrunc(strcpy(buf, inpname));
523     if (dotilt(inpfp, outfp, buf, tltid, outname, tltid) != 0) {
524     fprintf(stderr, "%s: bad tilt data\n", inpname);
525     goto readerr;
526     }
527 greg 2.12 if (dosource(&srcinfo, inpfp, outfp, tltid, outname) != 0) {
528 greg 1.1 fprintf(stderr, "%s: bad luminaire data\n", inpname);
529     goto readerr;
530     }
531     fclose(inpfp);
532 greg 2.12 /* cvgeometry closes outfp */
533     if (cvgeometry(geomfile, &srcinfo, outname, outfp) != 0) {
534     fprintf(stderr, "%s: bad geometry file\n", geomfile);
535     return(-1);
536     }
537 greg 1.1 return(0);
538     readerr:
539 greg 2.12 fclose(inpfp);
540 greg 1.1 fclose(outfp);
541 greg 2.18 unlink(fullnam(buf,outname,T_RAD));
542 greg 1.1 return(-1);
543     }
544    
545    
546     dotilt(in, out, dir, tltspec, dfltname, tltid) /* convert tilt data */
547     FILE *in, *out;
548     char *dir, *tltspec, *dfltname, *tltid;
549     {
550     int nangles, tlt_type;
551     double minmax[2];
552 schorsch 2.19 char buf[PATH_MAX], tltname[MAXWORD];
553 greg 1.1 FILE *datin, *datout;
554    
555     if (!strcmp(tltspec, TLTNONE)) {
556     datin = NULL;
557     strcpy(tltid, "void");
558     } else if (!strcmp(tltspec, TLTINCL)) {
559     datin = in;
560     strcpy(tltname, dfltname);
561     } else {
562 greg 2.4 if (ISDIRSEP(tltspec[0]))
563 greg 1.1 strcpy(buf, tltspec);
564     else
565 greg 2.4 strcpy(stradd(buf, dir, DIRSEP), tltspec);
566 greg 1.1 if ((datin = fopen(buf, "r")) == NULL) {
567     perror(buf);
568     return(-1);
569     }
570     tailtrunc(strcpy(tltname,filename(tltspec)));
571     }
572     if (datin != NULL) {
573 greg 2.18 if ((datout = fopen(fullnam(buf,tltname,T_TLT),"w")) == NULL) {
574 greg 1.1 perror(buf);
575     if (datin != in)
576     fclose(datin);
577     return(-1);
578     }
579 greg 2.6 if (!scnint(datin,&tlt_type) || !scnint(datin,&nangles)
580 greg 1.1 || cvdata(datin,datout,1,&nangles,1.,minmax) != 0) {
581     fprintf(stderr, "%s: data format error\n", tltspec);
582     fclose(datout);
583     if (datin != in)
584     fclose(datin);
585 greg 2.18 unlink(fullnam(buf,tltname,T_TLT));
586 greg 1.1 return(-1);
587     }
588     fclose(datout);
589     if (datin != in)
590     fclose(datin);
591     strcat(strcpy(tltid, filename(tltname)), "_tilt");
592     fprintf(out, "\nvoid brightdata %s\n", tltid);
593     libname(buf,tltname,T_TLT);
594     switch (tlt_type) {
595     case TLT_VERT: /* vertical */
596     fprintf(out, "4 noop %s tilt.cal %s\n", buf,
597     minmax[1]>90.+FTINY ? "tilt_ang" : "tilt_ang2");
598     break;
599     case TLT_H0: /* horiz. in 0 deg. plane */
600     fprintf(out, "6 noop %s tilt.cal %s -rz 90\n", buf,
601     minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
602     break;
603     case TLT_H90:
604     fprintf(out, "4 noop %s tilt.cal %s\n", buf,
605     minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
606     break;
607     default:
608     fprintf(stderr,
609     "%s: illegal lamp to luminaire geometry (%d)\n",
610     tltspec, tlt_type);
611     return(-1);
612     }
613     fprintf(out, "0\n0\n");
614     }
615     return(0);
616     }
617    
618    
619 greg 2.12 dosource(sinf, in, out, mod, name) /* create source and distribution */
620     SRCINFO *sinf;
621 greg 1.1 FILE *in, *out;
622     char *mod, *name;
623     {
624 schorsch 2.19 char buf[PATH_MAX], id[MAXWORD];
625 greg 1.1 FILE *datout;
626     double mult, bfactor, pfactor, width, length, height, wattage;
627     double bounds[2][2];
628     int nangles[2], pmtype, unitype;
629     double d1;
630 greg 2.18 int doupper, dolower, dosides;
631 greg 1.1
632 greg 2.6 if (!isint(getword(in)) || !isflt(getword(in)) || !scnflt(in,&mult)
633     || !scnint(in,&nangles[0]) || !scnint(in,&nangles[1])
634     || !scnint(in,&pmtype) || !scnint(in,&unitype)
635     || !scnflt(in,&width) || !scnflt(in,&length)
636     || !scnflt(in,&height) || !scnflt(in,&bfactor)
637     || !scnflt(in,&pfactor) || !scnflt(in,&wattage)) {
638 greg 1.1 fprintf(stderr, "dosource: bad lamp specification\n");
639     return(-1);
640     }
641 greg 2.12 sinf->mult = multiplier*mult*bfactor*pfactor;
642 greg 1.1 if (nangles[0] < 2 || nangles[1] < 1) {
643     fprintf(stderr, "dosource: too few measured angles\n");
644     return(-1);
645     }
646     if (unitype == U_FEET) {
647     width *= F_M;
648     length *= F_M;
649     height *= F_M;
650     }
651 greg 2.12 if (makeshape(sinf, width, length, height) != 0) {
652 greg 1.1 fprintf(stderr, "dosource: illegal source dimensions");
653     return(-1);
654     }
655 greg 2.18 if ((datout = fopen(fullnam(buf,name,T_DST), "w")) == NULL) {
656 greg 1.1 perror(buf);
657     return(-1);
658     }
659 greg 1.5 if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, bounds) != 0) {
660 greg 1.1 fprintf(stderr, "dosource: bad distribution data\n");
661     fclose(datout);
662 greg 2.18 unlink(fullnam(buf,name,T_DST));
663 greg 1.1 return(-1);
664     }
665     fclose(datout);
666     fprintf(out, "# %g watt luminaire, lamp*ballast factor = %g\n",
667     wattage, bfactor*pfactor);
668     strcat(strcpy(id, filename(name)), "_dist");
669     fprintf(out, "\n%s brightdata %s\n", mod, id);
670     if (nangles[1] < 2)
671     fprintf(out, "4 ");
672     else if (pmtype == PM_B)
673     fprintf(out, "5 ");
674     else if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
675 greg 2.7 fprintf(out, "7 ");
676 greg 1.1 else
677 greg 2.7 fprintf(out, "5 ");
678 greg 2.18 dolower = (bounds[0][0] < 90.);
679     doupper = (bounds[0][1] > 90.);
680     dosides = (doupper & dolower && sinf->h > MINDIM);
681 greg 1.1 fprintf(out, "%s %s source.cal ",
682 gregl 2.16 sinf->type==SPHERE ? "corr" :
683 greg 2.18 !dosides ? "flatcorr" :
684 gregl 2.16 sinf->type==DISK ? "cylcorr" : "boxcorr",
685 greg 1.1 libname(buf,name,T_DST));
686     if (pmtype == PM_B) {
687     if (FEQ(bounds[1][0],0.))
688     fprintf(out, "srcB_horiz2 ");
689     else
690     fprintf(out, "srcB_horiz ");
691     fprintf(out, "srcB_vert ");
692 greg 2.18 } else /* pmtype == PM_A */ {
693 greg 1.1 if (nangles[1] >= 2) {
694     d1 = bounds[1][1] - bounds[1][0];
695     if (d1 <= 90.+FTINY)
696     fprintf(out, "src_phi4 ");
697 greg 2.18 else if (d1 <= 180.+FTINY) {
698     if (FEQ(bounds[1][0],90.))
699     fprintf(out, "src_phi2+90 ");
700     else
701     fprintf(out, "src_phi2 ");
702     } else
703 greg 1.1 fprintf(out, "src_phi ");
704 greg 2.7 fprintf(out, "src_theta ");
705 greg 1.1 if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
706     fprintf(out, "-rz -90 ");
707     } else
708     fprintf(out, "src_theta ");
709     }
710 greg 2.18 if (!dosides || sinf->type == SPHERE)
711 gregl 2.16 fprintf(out, "\n0\n1 %g\n", sinf->mult/sinf->area);
712     else if (sinf->type == DISK)
713     fprintf(out, "\n0\n3 %g %g %g\n", sinf->mult,
714 greg 2.18 sinf->w, sinf->h);
715 gregl 2.16 else
716     fprintf(out, "\n0\n4 %g %g %g %g\n", sinf->mult,
717     sinf->l, sinf->w, sinf->h);
718 greg 2.12 if (putsource(sinf, out, id, filename(name),
719 greg 2.18 dolower, doupper, dosides) != 0)
720 greg 1.1 return(-1);
721     return(0);
722     }
723    
724    
725 greg 2.18 putsource(shp, fp, mod, name, dolower, doupper, dosides) /* put out source */
726 greg 2.12 SRCINFO *shp;
727 greg 1.1 FILE *fp;
728     char *mod, *name;
729     int dolower, doupper;
730     {
731 gregl 2.16 char lname[MAXWORD];
732 greg 1.1
733 gregl 2.16 strcat(strcpy(lname, name), "_light");
734     fprintf(fp, "\n%s %s %s\n", mod,
735     shp->isillum ? "illum" : "light", lname);
736 greg 1.1 fprintf(fp, "0\n0\n3 %g %g %g\n",
737 gregl 2.16 lampcolor[0], lampcolor[1], lampcolor[2]);
738 greg 1.1 switch (shp->type) {
739     case RECT:
740     if (dolower)
741 gregl 2.16 putrectsrc(shp, fp, lname, name, 0);
742 greg 1.1 if (doupper)
743 gregl 2.16 putrectsrc(shp, fp, lname, name, 1);
744     if (dosides)
745     putsides(shp, fp, lname, name);
746 greg 1.1 break;
747     case DISK:
748     if (dolower)
749 gregl 2.16 putdisksrc(shp, fp, lname, name, 0);
750 greg 1.1 if (doupper)
751 gregl 2.16 putdisksrc(shp, fp, lname, name, 1);
752     if (dosides)
753     putcyl(shp, fp, lname, name);
754 greg 1.1 break;
755     case SPHERE:
756 gregl 2.16 putspheresrc(shp, fp, lname, name);
757 greg 1.1 break;
758     }
759     return(0);
760     }
761    
762    
763     makeshape(shp, width, length, height) /* make source shape */
764 greg 2.12 register SRCINFO *shp;
765 greg 1.1 double width, length, height;
766     {
767 greg 2.11 if (illumrad/meters2out >= MINDIM/2.) {
768 greg 2.12 shp->isillum = 1;
769 greg 1.1 shp->type = SPHERE;
770 greg 2.11 shp->w = shp->l = shp->h = 2.*illumrad / meters2out;
771 greg 1.1 } else if (width < MINDIM) {
772     width = -width;
773     if (width < MINDIM) {
774     shp->type = SPHERE;
775     shp->w = shp->l = shp->h = MINDIM;
776     } else if (height < .5*width) {
777     shp->type = DISK;
778     shp->w = shp->l = width;
779     if (height >= MINDIM)
780     shp->h = height;
781     else
782     shp->h = .5*MINDIM;
783     } else {
784     shp->type = SPHERE;
785     shp->w = shp->l = shp->h = width;
786     }
787     } else {
788     shp->type = RECT;
789     shp->w = width;
790     if (length >= MINDIM)
791     shp->l = length;
792     else
793     shp->l = MINDIM;
794     if (height >= MINDIM)
795     shp->h = height;
796     else
797     shp->h = .5*MINDIM;
798     }
799     switch (shp->type) {
800     case RECT:
801     shp->area = shp->w * shp->l;
802     break;
803     case DISK:
804 greg 1.3 case SPHERE:
805 greg 1.1 shp->area = PI/4. * shp->w * shp->w;
806     break;
807     }
808     return(0);
809     }
810    
811    
812     putrectsrc(shp, fp, mod, name, up) /* rectangular source */
813 greg 2.12 SRCINFO *shp;
814 greg 1.1 FILE *fp;
815     char *mod, *name;
816     int up;
817     {
818     if (up)
819     putrect(shp, fp, mod, name, ".u", 4, 5, 7, 6);
820     else
821     putrect(shp, fp, mod, name, ".d", 0, 2, 3, 1);
822     }
823    
824    
825     putsides(shp, fp, mod, name) /* put out sides of box */
826 greg 2.12 register SRCINFO *shp;
827 greg 1.1 FILE *fp;
828     char *mod, *name;
829     {
830     putrect(shp, fp, mod, name, ".1", 0, 1, 5, 4);
831     putrect(shp, fp, mod, name, ".2", 1, 3, 7, 5);
832     putrect(shp, fp, mod, name, ".3", 3, 2, 6, 7);
833     putrect(shp, fp, mod, name, ".4", 2, 0, 4, 6);
834     }
835    
836    
837     putrect(shp, fp, mod, name, suffix, a, b, c, d) /* put out a rectangle */
838 greg 2.12 SRCINFO *shp;
839 greg 1.1 FILE *fp;
840     char *mod, *name, *suffix;
841     int a, b, c, d;
842     {
843     fprintf(fp, "\n%s polygon %s%s\n0\n0\n12\n", mod, name, suffix);
844     putpoint(shp, fp, a);
845     putpoint(shp, fp, b);
846     putpoint(shp, fp, c);
847     putpoint(shp, fp, d);
848     }
849    
850    
851     putpoint(shp, fp, p) /* put out a point */
852 greg 2.12 register SRCINFO *shp;
853 greg 1.1 FILE *fp;
854     int p;
855     {
856     static double mult[2] = {-.5, .5};
857    
858     fprintf(fp, "\t%g\t%g\t%g\n",
859     mult[p&1]*shp->l*meters2out,
860     mult[p>>1&1]*shp->w*meters2out,
861     mult[p>>2]*shp->h*meters2out);
862     }
863    
864    
865     putdisksrc(shp, fp, mod, name, up) /* put out a disk source */
866 greg 2.12 register SRCINFO *shp;
867 greg 1.1 FILE *fp;
868     char *mod, *name;
869     int up;
870     {
871     if (up) {
872     fprintf(fp, "\n%s ring %s.u\n", mod, name);
873     fprintf(fp, "0\n0\n8\n");
874     fprintf(fp, "\t0 0 %g\n", .5*shp->h*meters2out);
875     fprintf(fp, "\t0 0 1\n");
876     fprintf(fp, "\t0 %g\n", .5*shp->w*meters2out);
877     } else {
878     fprintf(fp, "\n%s ring %s.d\n", mod, name);
879     fprintf(fp, "0\n0\n8\n");
880     fprintf(fp, "\t0 0 %g\n", -.5*shp->h*meters2out);
881     fprintf(fp, "\t0 0 -1\n");
882     fprintf(fp, "\t0 %g\n", .5*shp->w*meters2out);
883     }
884     }
885    
886    
887     putcyl(shp, fp, mod, name) /* put out a cylinder */
888 greg 2.12 register SRCINFO *shp;
889 greg 1.1 FILE *fp;
890     char *mod, *name;
891     {
892     fprintf(fp, "\n%s cylinder %s.c\n", mod, name);
893     fprintf(fp, "0\n0\n7\n");
894     fprintf(fp, "\t0 0 %g\n", .5*shp->h*meters2out);
895     fprintf(fp, "\t0 0 %g\n", -.5*shp->h*meters2out);
896     fprintf(fp, "\t%g\n", .5*shp->w*meters2out);
897     }
898    
899    
900     putspheresrc(shp, fp, mod, name) /* put out a sphere source */
901 greg 2.12 SRCINFO *shp;
902 greg 1.1 FILE *fp;
903     char *mod, *name;
904     {
905     fprintf(fp, "\n%s sphere %s.s\n", mod, name);
906     fprintf(fp, "0\n0\n4 0 0 0 %g\n", .5*shp->w*meters2out);
907     }
908    
909    
910     cvdata(in, out, ndim, npts, mult, lim) /* convert data */
911     FILE *in, *out;
912     int ndim, npts[];
913     double mult, lim[][2];
914     {
915 greg 2.3 double *pt[4];
916 greg 1.1 register int i, j;
917     double val;
918     int total;
919    
920     total = 1; j = 0;
921     for (i = 0; i < ndim; i++)
922     if (npts[i] > 1) {
923     total *= npts[i];
924     j++;
925     }
926     fprintf(out, "%d\n", j);
927     /* get coordinates */
928     for (i = 0; i < ndim; i++) {
929     pt[i] = (double *)malloc(npts[i]*sizeof(double));
930     for (j = 0; j < npts[i]; j++)
931 greg 2.6 if (!scnflt(in, &pt[i][j]))
932     return(-1);
933 greg 1.1 if (lim != NULL) {
934     lim[i][0] = pt[i][0];
935     lim[i][1] = pt[i][npts[i]-1];
936     }
937     }
938     /* write out in reverse */
939     for (i = ndim-1; i >= 0; i--) {
940     if (npts[i] > 1) {
941     for (j = 1; j < npts[i]-1; j++)
942     if (!FEQ(pt[i][j]-pt[i][j-1],
943     pt[i][j+1]-pt[i][j]))
944     break;
945     if (j == npts[i]-1)
946     fprintf(out, "%g %g %d\n", pt[i][0], pt[i][j],
947     npts[i]);
948     else {
949     fprintf(out, "0 0 %d", npts[i]);
950     for (j = 0; j < npts[i]; j++) {
951     if (j%4 == 0)
952     putc('\n', out);
953     fprintf(out, "\t%g", pt[i][j]);
954     }
955     putc('\n', out);
956     }
957     }
958 greg 2.18 free((void *)pt[i]);
959 greg 1.1 }
960     for (i = 0; i < total; i++) {
961     if (i%4 == 0)
962     putc('\n', out);
963 greg 2.6 if (!scnflt(in, &val))
964 greg 1.1 return(-1);
965     fprintf(out, "\t%g", val*mult);
966     }
967     putc('\n', out);
968     return(0);
969 greg 2.6 }
970    
971    
972     char *
973     getword(fp) /* scan a word from fp */
974     register FILE *fp;
975     {
976 gregl 2.17 static char wrd[MAXWORD];
977 greg 2.6 register char *cp;
978     register int c;
979    
980     while (isspace(c=getc(fp)))
981     ;
982 gregl 2.17 for (cp = wrd; c != EOF && cp < wrd+MAXWORD-1;
983 greg 2.6 *cp++ = c, c = getc(fp))
984     if (isspace(c) || c == ',') {
985     while (isspace(c))
986     c = getc(fp);
987     if (c != EOF & c != ',')
988     ungetc(c, fp);
989     *cp = '\0';
990 gregl 2.17 return(wrd);
991 greg 2.6 }
992     *cp = '\0';
993 gregl 2.17 return(cp > wrd ? wrd : NULL);
994 greg 2.6 }
995    
996    
997 gregl 2.17 cvtint(ip, wrd) /* convert a word to an integer */
998 greg 2.6 int *ip;
999 gregl 2.17 char *wrd;
1000 greg 2.6 {
1001 gregl 2.17 if (wrd == NULL || !isint(wrd))
1002 greg 2.6 return(0);
1003 gregl 2.17 *ip = atoi(wrd);
1004 greg 2.6 return(1);
1005     }
1006    
1007    
1008 gregl 2.17 cvtflt(rp, wrd) /* convert a word to a double */
1009 greg 2.6 double *rp;
1010 gregl 2.17 char *wrd;
1011 greg 2.6 {
1012 gregl 2.17 if (wrd == NULL || !isflt(wrd))
1013 greg 2.6 return(0);
1014 gregl 2.17 *rp = atof(wrd);
1015 greg 2.6 return(1);
1016 greg 2.12 }
1017    
1018    
1019     cvgeometry(inpname, sinf, outname, outfp)
1020     char *inpname;
1021     register SRCINFO *sinf;
1022     char *outname;
1023     FILE *outfp; /* close output file upon return */
1024     {
1025     char buf[256];
1026     register char *cp;
1027    
1028     if (inpname == NULL || !inpname[0]) { /* no geometry file */
1029     fclose(outfp);
1030     return(0);
1031     }
1032     putc('\n', outfp);
1033     strcpy(buf, "mgf2rad "); /* build mgf2rad command */
1034     cp = buf+8;
1035     if (!FEQ(sinf->mult, 1.0)) {
1036     sprintf(cp, "-m %f ", sinf->mult);
1037     cp += strlen(cp);
1038     }
1039     sprintf(cp, "-g %f %s ",
1040     sqrt(sinf->w*sinf->w + sinf->h*sinf->h + sinf->l*sinf->l),
1041     inpname);
1042     cp += strlen(cp);
1043     if (instantiate) { /* instantiate octree */
1044     strcpy(cp, "| oconv - > ");
1045     cp += 12;
1046 greg 2.18 fullnam(cp,outname,T_OCT);
1047 greg 2.14 if (fdate(inpname) > fdate(outname) &&
1048     system(buf)) { /* create octree */
1049 greg 2.12 fclose(outfp);
1050     return(-1);
1051     }
1052     fprintf(outfp, "void instance %s_inst\n", outname);
1053     if (!FEQ(meters2out, 1.0))
1054     fprintf(outfp, "3 %s -s %f\n",
1055     libname(buf,outname,T_OCT),
1056     meters2out);
1057     else
1058     fprintf(outfp, "1 %s\n", libname(buf,outname,T_OCT));
1059     fprintf(outfp, "0\n0\n");
1060     fclose(outfp);
1061     } else { /* else append to luminaire file */
1062     if (!FEQ(meters2out, 1.0)) { /* apply scalefactor */
1063     sprintf(cp, "| xform -s %f ", meters2out);
1064     cp += strlen(cp);
1065     }
1066 greg 2.13 if (!out2stdout) {
1067     fclose(outfp);
1068     strcpy(cp, ">> "); /* append works for DOS? */
1069     cp += 3;
1070 greg 2.18 fullnam(cp,outname,T_RAD);
1071 greg 2.13 }
1072 greg 2.12 if (system(buf))
1073     return(-1);
1074     }
1075     return(0);
1076 greg 1.1 }