ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.14
Committed: Tue Jun 18 21:28:52 1996 UTC (27 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +4 -1 lines
Log Message:
added check to avoid rerunning oconv unnecessarily

File Contents

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