ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.12
Committed: Tue Apr 25 21:37:14 1995 UTC (29 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +189 -31 lines
Log Message:
added MGF detail geometry conversion

File Contents

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