ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
(Generate patch)

Comparing ray/src/cv/ies2rad.c (file contents):
Revision 1.1 by greg, Tue Dec 11 08:45:48 1990 UTC vs.
Revision 2.23 by schorsch, Sat Nov 15 13:29:23 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1990 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Convert IES luminaire data to Radiance description
6   *
7   *      07Apr90         Greg Ward
8 + *
9 + *  Fixed correction factor for flat sources 29Oct2001 GW
10   */
11  
12   #include <stdio.h>
13 + #include <string.h>
14 + #include <math.h>
15 + #include <sys/types.h>
16   #include <ctype.h>
17  
18 + #include "rtio.h"
19 + #include "color.h"
20 + #include "paths.h"
21 +
22   #define PI              3.14159265358979323846
23                                          /* floating comparisons */
24   #define FTINY           1e-6
25   #define FEQ(a,b)        ((a)<=(b)+FTINY&&(a)>=(b)-FTINY)
26 +                                        /* keywords */
27 + #define MAGICID         "IESNA"
28 + #define LMAGICID        5
29 + #define FIRSTREV        86
30 + #define LASTREV         95
31 +
32 + #define D86             0               /* keywords defined in LM-63-1986 */
33 +
34 + #define K_TST           0
35 + #define K_MAN           1
36 + #define K_LMC           2
37 + #define K_LMN           3
38 + #define K_LPC           4
39 + #define K_LMP           5
40 + #define K_BAL           6
41 + #define K_MTC           7
42 + #define K_OTH           8
43 + #define K_SCH           9
44 + #define K_MOR           10
45 + #define K_BLK           11
46 + #define K_EBK           12
47 +
48 + #define D91             ((1L<<13)-1)    /* keywords defined in LM-63-1991 */
49 +
50 + #define K_LMG           13
51 +
52 + #define D95             ((1L<<14)-1)    /* keywords defined in LM-63-1995 */
53 +
54 + char    k_kwd[][20] = {"TEST", "MANUFAC", "LUMCAT", "LUMINAIRE", "LAMPCAT",
55 +                        "LAMP", "BALLAST", "MAINTCAT", "OTHER", "SEARCH",
56 +                        "MORE", "BLOCK", "ENDBLOCK", "LUMINOUSGEOMETRY"};
57 +
58 + long k_defined[] = {D86, D86, D86, D86, D86, D91, D91, D91, D91, D95};
59 +
60 + int     filerev = FIRSTREV;
61 +
62 + #define keymatch(i,s)   (k_defined[filerev-FIRSTREV]&1L<<(i) &&\
63 +                                k_match(k_kwd[i],s))
64 +
65 + #define checklamp(s)    (!(k_defined[filerev-FIRSTREV]&(1<<K_LMP|1<<K_LPC)) ||\
66 +                                keymatch(K_LMP,s) || keymatch(K_LPC,s))
67 +
68                                          /* tilt specs */
69   #define TLTSTR          "TILT="
70   #define TLTSTRLEN       5
# Line 33 | Line 81 | static char SCCSid[] = "$SunId$ LBL";
81   #define U_METERS        2
82                                          /* string lengths */
83   #define MAXLINE         132
84 < #define MAXWORD         76
37 < #define MAXPATH         128
84 > #define RMAXWORD        76
85                                          /* file types */
86   #define T_RAD           ".rad"
87   #define T_DST           ".dat"
88 < #define T_TLT           "+.dat"
88 > #define T_TLT           "%.dat"
89 > #define T_OCT           ".oct"
90                                          /* shape types */
91   #define RECT            1
92   #define DISK            2
# Line 48 | Line 96 | static char SCCSid[] = "$SunId$ LBL";
96  
97   #define F_M             .3048           /* feet to meters */
98  
99 < #define abspath(p)      ((p)[0] == '/' || (p)[0] == '.')
99 > #define abspath(p)      (ISDIRSEP((p)[0]) || (p)[0] == '.')
100  
101 + static char     default_name[] = "default";
102 +
103   char    *libdir = NULL;                 /* library directory location */
104   char    *prefdir = NULL;                /* subdirectory */
105   char    *lampdat = "lamp.tab";          /* lamp data file */
106  
107   double  meters2out = 1.0;               /* conversion from meters to output */
108   char    *lamptype = NULL;               /* selected lamp type */
109 < float   *lampcolor = NULL;              /* pointer to lamp color */
109 > char    *deflamp = NULL;                /* default lamp type */
110   float   defcolor[3] = {1.,1.,1.};       /* default lamp color */
111 + float   *lampcolor = defcolor;          /* pointer to current lamp color */
112   double  multiplier = 1.0;               /* multiplier for all light sources */
113   char    units[64] = "meters";           /* output units */
114 < double  minaspect = 0.0;                /* minimum allowed aspect ratio */
115 < int     maxemitters = 1;                /* maximum emitters per hemisphere */
114 > int     out2stdout = 0;                 /* put out to stdout r.t. file */
115 > int     instantiate = 0;                /* instantiate geometry */
116   double  illumrad = 0.0;                 /* radius for illum sphere */
117  
118   typedef struct {
119 +        int     isillum;                        /* do as illum */
120          int     type;                           /* RECT, DISK, SPHERE */
121 +        double  mult;                           /* candela multiplier */
122          double  w, l, h;                        /* width, length, height */
123 <        double  area;                           /* effective radiating area */
124 < } SHAPE;                                /* a source shape */
123 >        double  area;                           /* max. projected area */
124 > } SRCINFO;                              /* a source shape (units=meters) */
125  
126   int     gargc;                          /* global argc (minus filenames) */
127   char    **gargv;                        /* global argv */
128  
76 extern char     *strcpy(), *strcat(), *stradd(), *tailtrunc(), *filetrunc(),
77                *filename(), *libname(), *fullname(), *malloc();
78 extern double   atof();
79 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 < main(argc, argv)
135 < int     argc;
136 < char    *argv[];
134 >
135 > static int ies2rad(char *inpname, char *outname);
136 > static void initlamps(void);
137 > static int dosource(SRCINFO *sinf, FILE *in, FILE *out, char *mod, char *name);
138 > static int dotilt(FILE *in, FILE *out, char *dir, char *tltspec,
139 >                char *dfltname, char *tltid);
140 > static int cvgeometry(char *inpname, SRCINFO *sinf, char *outname, FILE *outfp);
141 > static int cvtint(int *ip, char *wrd);
142 > static int cvdata(FILE *in, FILE *out, int ndim, int npts[], double mult,
143 >                double lim[][2]);
144 > static int cvtflt(double *rp, char *wrd);
145 > static int makeshape(SRCINFO *shp, double width, double length, double height);
146 > static int putsource(SRCINFO *shp, FILE *fp, char *mod, char *name,
147 >                int dolower, int doupper, int dosides);
148 > static void putrectsrc(SRCINFO *shp, FILE *fp, char *mod, char *name, int up);
149 > static void putsides(SRCINFO *shp, FILE *fp, char *mod, char *name);
150 > static void putdisksrc(SRCINFO *shp, FILE *fp, char *mod, char *name, int up);
151 > static void putspheresrc(SRCINFO *shp, FILE *fp, char *mod, char *name);
152 > static void putrect(SRCINFO *shp, FILE *fp, char *mod, char *name, char *suffix,
153 >                int a, int b, int c, int d);
154 > static void putpoint(SRCINFO *shp, FILE *fp, int p);
155 > static void putcyl(SRCINFO *shp, FILE *fp, char *mod, char *name);
156 > static char * tailtrunc(char *name);
157 > static char * filename(char *path);
158 > static char * libname(char *path, char *fname, char *suffix);
159 > static char * getword(FILE *fp);
160 > static char * fullnam(char *path, char *fname, char *suffix);
161 >
162 >
163 > int
164 > main(
165 >        int     argc,
166 >        char    *argv[]
167 > )
168   {
169          char    *outfile = NULL;
170          int     status;
171 <        char    outname[MAXWORD];
171 >        char    outname[RMAXWORD];
172          double  d1;
173          int     i;
174          
# Line 150 | Line 233 | char   *argv[];
233                  case 'f':               /* lamp data file */
234                          lampdat = argv[++i];
235                          break;
236 <                case 'o':               /* output file name */
236 >                case 'o':               /* output file root name */
237                          outfile = argv[++i];
238                          break;
239 <                case 's':               /* square emitters */
240 <                        minaspect = .6;
158 <                        if (argv[i][2] == '/') {
159 <                                maxemitters = atoi(argv[i]+3);
160 <                                if (maxemitters < 1)
161 <                                        goto badopt;
162 <                        }
239 >                case 's':               /* output to stdout */
240 >                        out2stdout = !out2stdout;
241                          break;
242                  case 'i':               /* illum */
243                          illumrad = atof(argv[++i]);
166                        if (illumrad < MINDIM)
167                                illumrad = MINDIM;
244                          break;
245 <                case 't':               /* select lamp type */
245 >                case 'g':               /* instatiate geometry? */
246 >                        instantiate = !instantiate;
247 >                        break;
248 >                case 't':               /* override lamp type */
249                          lamptype = argv[++i];
250                          break;
251 +                case 'u':               /* default lamp type */
252 +                        deflamp = argv[++i];
253 +                        break;
254                  case 'c':               /* default lamp color */
255                          defcolor[0] = atof(argv[++i]);
256                          defcolor[1] = atof(argv[++i]);
# Line 185 | Line 267 | char   *argv[];
267                  }
268          gargc = i;
269          gargv = argv;
270 <                                        /* get lamp data */
189 <        if ((status = loadlamps(lampdat)) < 0)
190 <                exit(1);
191 <        if (status == 0 || (lamptype != NULL &&
192 <                        (lampcolor = matchlamp(lamptype)) == NULL)) {
193 <                lampcolor = defcolor;
194 <                fprintf(stderr, "%s: warning - no lamp data\n", argv[0]);
195 <        }
270 >        initlamps();                    /* get lamp data (if needed) */
271                                          /* convert ies file(s) */
272          if (outfile != NULL) {
273                  if (i == argc)
274                          exit(ies2rad(NULL, outfile) == 0 ? 0 : 1);
275                  else if (i == argc-1)
276                          exit(ies2rad(argv[i], outfile) == 0 ? 0 : 1);
277 <                else {
278 <                        fprintf(stderr, "%s: single input file required\n",
204 <                                        argv[0]);
205 <                        exit(1);
206 <                }
277 >                else
278 >                        goto needsingle;
279          } else if (i >= argc) {
280                  fprintf(stderr, "%s: missing output file specification\n",
281                                  argv[0]);
282                  exit(1);
283          }
284 +        if (out2stdout && i != argc-1)
285 +                goto needsingle;
286          status = 0;
287          for ( ; i < argc; i++) {
288                  tailtrunc(strcpy(outname,filename(argv[i])));
# Line 216 | Line 290 | char   *argv[];
290                          status = 1;
291          }
292          exit(status);
293 + needsingle:
294 +        fprintf(stderr, "%s: single input file required\n", argv[0]);
295 +        exit(1);
296   }
297  
298 + void
299 + initlamps(void)                         /* set up lamps */
300 + {
301 +        float   *lcol;
302 +        int     status;
303  
304 +        if (lamptype != NULL && !strcmp(lamptype, default_name) &&
305 +                        deflamp == NULL)
306 +                return;                         /* no need for data */
307 +                                                /* else load file */
308 +        if ((status = loadlamps(lampdat)) < 0)
309 +                exit(1);
310 +        if (status == 0) {
311 +                fprintf(stderr, "%s: warning - no lamp data\n", lampdat);
312 +                lamptype = default_name;
313 +                return;
314 +        }
315 +        if (deflamp != NULL) {                  /* match default type */
316 +                if ((lcol = matchlamp(deflamp)) == NULL)
317 +                        fprintf(stderr,
318 +                                "%s: warning - unknown default lamp type\n",
319 +                                        deflamp);
320 +                else
321 +                        copycolor(defcolor, lcol);
322 +        }
323 +        if (lamptype != NULL) {                 /* match selected type */
324 +                if (strcmp(lamptype, default_name)) {
325 +                        if ((lcol = matchlamp(lamptype)) == NULL) {
326 +                                fprintf(stderr,
327 +                                        "%s: warning - unknown lamp type\n",
328 +                                                lamptype);
329 +                                lamptype = default_name;
330 +                        } else
331 +                                copycolor(defcolor, lcol);
332 +                }
333 +                freelamps();                    /* all done with data */
334 +        }
335 +                                                /* else keep lamp data */
336 + }
337 +
338 +
339   char *
340 < stradd(dst, src, sep)                   /* add a string at dst */
341 < register char   *dst, *src;
342 < int     sep;
340 > stradd(                 /* add a string at dst */
341 >        register char   *dst,
342 >        register char   *src,
343 >        int     sep
344 > )
345   {
346          if (src && *src) {
347                  do
# Line 237 | Line 356 | int    sep;
356  
357  
358   char *
359 < fullname(path, fname, suffix)           /* return full path name */
360 < char    *path, *fname, *suffix;
359 > fullnam(                /* return full path name */
360 >        char    *path,
361 >        char    *fname,
362 >        char    *suffix
363 > )
364   {
365          if (prefdir != NULL && abspath(prefdir))
366                  libname(path, fname, suffix);
367          else if (abspath(fname))
368                  strcpy(stradd(path, fname, 0), suffix);
369          else
370 <                libname(stradd(path, libdir, '/'), fname, suffix);
370 >                libname(stradd(path, libdir, DIRSEP), fname, suffix);
371  
372          return(path);
373   }
374  
375  
376   char *
377 < libname(path, fname, suffix)            /* return library relative name */
378 < char    *path, *fname, *suffix;
377 > libname(                /* return library relative name */
378 >        char    *path,
379 >        char    *fname,
380 >        char    *suffix
381 > )
382   {
383          if (abspath(fname))
384                  strcpy(stradd(path, fname, 0), suffix);
385          else
386 <                strcpy(stradd(stradd(path, prefdir, '/'), fname, 0), suffix);
386 >                strcpy(stradd(stradd(path, prefdir, DIRSEP), fname, 0), suffix);
387  
388          return(path);
389   }
390  
391  
392   char *
393 < filename(path)                  /* get final component of pathname */
394 < register char   *path;
393 > filename(                       /* get final component of pathname */
394 >        register char   *path
395 > )
396   {
397          register char   *cp;
398  
399          for (cp = path; *path; path++)
400 <                if (*path == '/')
400 >                if (ISDIRSEP(*path))
401                          cp = path+1;
402          return(cp);
403   }
404  
405  
406   char *
407 < filetrunc(path)                         /* truncate filename at end of path */
408 < char    *path;
407 > filetrunc(                              /* truncate filename at end of path */
408 >        char    *path
409 > )
410   {
411          register char   *p1, *p2;
412  
413          for (p1 = p2 = path; *p2; p2++)
414 <                if (*p2 == '/')
414 >                if (ISDIRSEP(*p2))
415                          p1 = p2;
416 +        if (p1 == path && ISDIRSEP(*p1))
417 +                p1++;
418          *p1 = '\0';
419          return(path);
420   }
421  
422  
423   char *
424 < tailtrunc(name)                         /* truncate tail of filename */
425 < char    *name;
424 > tailtrunc(                              /* truncate tail of filename */
425 >        char    *name
426 > )
427   {
428          register char   *p1, *p2;
429  
# Line 309 | Line 439 | char   *name;
439   }
440  
441  
442 < blanktrunc(s)                           /* truncate spaces at end of line */
443 < char    *s;
442 > void
443 > blanktrunc(                             /* truncate spaces at end of line */
444 >        char    *s
445 > )
446   {
447          register char   *cp;
448  
# Line 322 | Line 454 | char   *s;
454   }
455  
456  
457 < putheader(out)                          /* print header */
458 < FILE    *out;
457 > int
458 > k_match(                        /* header line matches keyword? */
459 >        register char   *kwd,
460 >        register char   *hdl
461 > )
462   {
463 +        if (!*hdl++ == '[')
464 +                return(0);
465 +        while (islower(*hdl) ? toupper(*hdl) == *kwd++ : *hdl == *kwd++)
466 +                if (!*hdl++)
467 +                        return(0);
468 +        return((!*kwd) & (*hdl == ']'));
469 + }
470 +
471 +
472 + char *
473 + keyargs(                                /* return keyword arguments */
474 +        register char   *hdl
475 + )
476 + {
477 +        while (*hdl && *hdl++ != ']')
478 +                ;
479 +        while (isspace(*hdl))
480 +                hdl++;
481 +        return(hdl);
482 + }
483 +
484 +
485 + void
486 + putheader(                              /* print header */
487 +        FILE    *out
488 + )
489 + {
490          register int    i;
491          
492          putc('#', out);
# Line 338 | Line 500 | FILE   *out;
500   }
501  
502  
503 < ies2rad(inpname, outname)               /* convert IES file */
504 < char    *inpname, *outname;
503 > int
504 > ies2rad(                /* convert IES file */
505 >        char    *inpname,
506 >        char    *outname
507 > )
508   {
509 <        char    buf[MAXLINE], tltid[MAXWORD];
509 >        SRCINFO srcinfo;
510 >        char    buf[MAXLINE], tltid[RMAXWORD];
511 >        char    geomfile[128];
512          FILE    *inpfp, *outfp;
513 +        int     lineno = 0;
514  
515 +        geomfile[0] = '\0';
516 +        srcinfo.isillum = 0;
517          if (inpname == NULL) {
518                  inpname = "<stdin>";
519                  inpfp = stdin;
# Line 351 | Line 521 | char   *inpname, *outname;
521                  perror(inpname);
522                  return(-1);
523          }
524 <        if ((outfp = fopen(fullname(buf,outname,T_RAD), "w")) == NULL) {
524 >        if (out2stdout)
525 >                outfp = stdout;
526 >        else if ((outfp = fopen(fullnam(buf,outname,T_RAD), "w")) == NULL) {
527                  perror(buf);
528                  fclose(inpfp);
529                  return(-1);
# Line 364 | Line 536 | char   *inpname, *outname;
536                  blanktrunc(buf);
537                  if (!buf[0])
538                          continue;
539 +                if (!lineno++ && !strncmp(buf, MAGICID, LMAGICID)) {
540 +                        filerev = atoi(buf+LMAGICID);
541 +                        if (filerev < FIRSTREV)
542 +                                filerev = FIRSTREV;
543 +                        else if (filerev > LASTREV)
544 +                                filerev = LASTREV;
545 +                }
546                  fputs("#<", outfp);
547                  fputs(buf, outfp);
548                  putc('\n', outfp);
549 <                if (lampcolor == NULL)
550 <                        lampcolor = matchlamp(buf);
549 >                if (lampcolor == NULL && checklamp(buf))
550 >                        lampcolor = matchlamp( buf[0] == '[' ?
551 >                                                keyargs(buf) : buf );
552 >                if (keymatch(K_LMG, buf)) {             /* geometry file */
553 >                        strcpy(geomfile, inpname);
554 >                        strcpy(filename(geomfile), keyargs(buf));
555 >                        srcinfo.isillum = 1;
556 >                }
557          }
558          if (lampcolor == NULL) {
559                  fprintf(stderr, "%s: warning - no lamp type\n", inpname);
560 +                fputs("# Unknown lamp type (used default)\n", outfp);
561                  lampcolor = defcolor;
562 <        }
562 >        } else if (lamptype == NULL)
563 >                fprintf(outfp,"# CIE(x,y) = (%f,%f)\n# Depreciation = %.1f%%\n",
564 >                                lampcolor[3], lampcolor[4], 100.*lampcolor[5]);
565          if (feof(inpfp)) {
566                  fprintf(stderr, "%s: not in IES format\n", inpname);
567                  goto readerr;
568          }
569 <        sscanf(buf+TLTSTRLEN, "%s", tltid);
569 >        atos(tltid, RMAXWORD, buf+TLTSTRLEN);
570          if (inpfp == stdin)
571                  buf[0] = '\0';
572          else
# Line 387 | Line 575 | char   *inpname, *outname;
575                  fprintf(stderr, "%s: bad tilt data\n", inpname);
576                  goto readerr;
577          }
578 <        if (dosource(inpfp, outfp, tltid, outname) != 0) {
578 >        if (dosource(&srcinfo, inpfp, outfp, tltid, outname) != 0) {
579                  fprintf(stderr, "%s: bad luminaire data\n", inpname);
580                  goto readerr;
581          }
394        fclose(outfp);
582          fclose(inpfp);
583 +                                        /* cvgeometry closes outfp */
584 +        if (cvgeometry(geomfile, &srcinfo, outname, outfp) != 0) {
585 +                fprintf(stderr, "%s: bad geometry file\n", geomfile);
586 +                return(-1);
587 +        }
588          return(0);
589   readerr:
398        fclose(outfp);
590          fclose(inpfp);
591 <        unlink(fullname(buf,outname,T_RAD));
591 >        fclose(outfp);
592 >        unlink(fullnam(buf,outname,T_RAD));
593          return(-1);
594   }
595  
596  
597 < dotilt(in, out, dir, tltspec, dfltname, tltid)  /* convert tilt data */
598 < FILE    *in, *out;
599 < char    *dir, *tltspec, *dfltname, *tltid;
597 > int
598 > dotilt( /* convert tilt data */
599 >        FILE    *in,
600 >        FILE    *out,
601 >        char    *dir,
602 >        char    *tltspec,
603 >        char    *dfltname,
604 >        char    *tltid
605 > )
606   {
607          int     nangles, tlt_type;
608 <        double  minmax[2];
609 <        char    buf[MAXPATH], tltname[MAXWORD];
608 >        double  minmax[1][2];
609 >        char    buf[PATH_MAX], tltname[RMAXWORD];
610          FILE    *datin, *datout;
611  
612          if (!strcmp(tltspec, TLTNONE)) {
# Line 418 | Line 616 | char   *dir, *tltspec, *dfltname, *tltid;
616                  datin = in;
617                  strcpy(tltname, dfltname);
618          } else {
619 <                if (tltspec[0] == '/')
619 >                if (ISDIRSEP(tltspec[0]))
620                          strcpy(buf, tltspec);
621                  else
622 <                        strcpy(stradd(buf, dir, '/'), tltspec);
622 >                        strcpy(stradd(buf, dir, DIRSEP), tltspec);
623                  if ((datin = fopen(buf, "r")) == NULL) {
624                          perror(buf);
625                          return(-1);
# Line 429 | Line 627 | char   *dir, *tltspec, *dfltname, *tltid;
627                  tailtrunc(strcpy(tltname,filename(tltspec)));
628          }
629          if (datin != NULL) {
630 <                if ((datout = fopen(fullname(buf,tltname,T_TLT),"w")) == NULL) {
630 >                if ((datout = fopen(fullnam(buf,tltname,T_TLT),"w")) == NULL) {
631                          perror(buf);
632                          if (datin != in)
633                                  fclose(datin);
634                          return(-1);
635                  }
636 <                if (fscanf(datin, "%d %d", &tlt_type, &nangles) != 2
636 >                if (!scnint(datin,&tlt_type) || !scnint(datin,&nangles)
637                          || cvdata(datin,datout,1,&nangles,1.,minmax) != 0) {
638                          fprintf(stderr, "%s: data format error\n", tltspec);
639                          fclose(datout);
640                          if (datin != in)
641                                  fclose(datin);
642 <                        unlink(fullname(buf,tltname,T_TLT));
642 >                        unlink(fullnam(buf,tltname,T_TLT));
643                          return(-1);
644                  }
645                  fclose(datout);
# Line 453 | Line 651 | char   *dir, *tltspec, *dfltname, *tltid;
651                  switch (tlt_type) {
652                  case TLT_VERT:                  /* vertical */
653                          fprintf(out, "4 noop %s tilt.cal %s\n", buf,
654 <                                minmax[1]>90.+FTINY ? "tilt_ang" : "tilt_ang2");
654 >                                minmax[0][1]>90.+FTINY ? "tilt_ang" : "tilt_ang2");
655                          break;
656                  case TLT_H0:                    /* horiz. in 0 deg. plane */
657                          fprintf(out, "6 noop %s tilt.cal %s -rz 90\n", buf,
658 <                        minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
658 >                        minmax[0][1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
659                          break;
660                  case TLT_H90:
661                          fprintf(out, "4 noop %s tilt.cal %s\n", buf,
662 <                        minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
662 >                        minmax[0][1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
663                          break;
664                  default:
665                          fprintf(stderr,
# Line 475 | Line 673 | char   *dir, *tltspec, *dfltname, *tltid;
673   }
674  
675  
676 < dosource(in, out, mod, name)            /* create source and distribution */
677 < FILE    *in, *out;
678 < char    *mod, *name;
676 > int
677 > dosource(       /* create source and distribution */
678 >        SRCINFO *sinf,
679 >        FILE    *in,
680 >        FILE    *out,
681 >        char    *mod,
682 >        char    *name
683 > )
684   {
685 <        SHAPE   srcshape;
483 <        char    buf[MAXPATH], id[MAXWORD];
685 >        char    buf[PATH_MAX], id[RMAXWORD];
686          FILE    *datout;
687          double  mult, bfactor, pfactor, width, length, height, wattage;
688          double  bounds[2][2];
689          int     nangles[2], pmtype, unitype;
690          double  d1;
691 +        int     doupper, dolower, dosides;
692  
693 <        if (fscanf(in, "%*d %*f %lf %d %d %d %d %lf %lf %lf %lf %lf %lf",
694 <                        &mult, &nangles[0], &nangles[1], &pmtype, &unitype,
695 <                        &width, &length, &height, &bfactor, &pfactor,
696 <                        &wattage) != 11) {
693 >        if (!isint(getword(in)) || !isflt(getword(in)) || !scnflt(in,&mult)
694 >                        || !scnint(in,&nangles[0]) || !scnint(in,&nangles[1])
695 >                        || !scnint(in,&pmtype) || !scnint(in,&unitype)
696 >                        || !scnflt(in,&width) || !scnflt(in,&length)
697 >                        || !scnflt(in,&height) || !scnflt(in,&bfactor)
698 >                        || !scnflt(in,&pfactor) || !scnflt(in,&wattage)) {
699                  fprintf(stderr, "dosource: bad lamp specification\n");
700                  return(-1);
701          }
702 +        sinf->mult = multiplier*mult*bfactor*pfactor;
703          if (nangles[0] < 2 || nangles[1] < 1) {
704                  fprintf(stderr, "dosource: too few measured angles\n");
705                  return(-1);
# Line 503 | Line 709 | char   *mod, *name;
709                  length *= F_M;
710                  height *= F_M;
711          }
712 <        if (makeshape(&srcshape, width, length, height) != 0) {
712 >        if (makeshape(sinf, width, length, height) != 0) {
713                  fprintf(stderr, "dosource: illegal source dimensions");
714                  return(-1);
715          }
716 <        if ((datout = fopen(fullname(buf,name,T_DST), "w")) == NULL) {
716 >        if ((datout = fopen(fullnam(buf,name,T_DST), "w")) == NULL) {
717                  perror(buf);
718                  return(-1);
719          }
720 <        if (cvdata(in, datout, 2, nangles, 1./683., bounds) != 0) {
720 >        if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, bounds) != 0) {
721                  fprintf(stderr, "dosource: bad distribution data\n");
722                  fclose(datout);
723 <                unlink(fullname(buf,name,T_DST));
723 >                unlink(fullnam(buf,name,T_DST));
724                  return(-1);
725          }
726          fclose(datout);
# Line 527 | Line 733 | char   *mod, *name;
733          else if (pmtype == PM_B)
734                  fprintf(out, "5 ");
735          else if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
736 <                fprintf(out, "8 ");
736 >                fprintf(out, "7 ");
737          else
738 <                fprintf(out, "6 ");
738 >                fprintf(out, "5 ");
739 >        dolower = (bounds[0][0] < 90.);
740 >        doupper = (bounds[0][1] > 90.);
741 >        dosides = (doupper & dolower && sinf->h > MINDIM);
742          fprintf(out, "%s %s source.cal ",
743 <                        srcshape.type==SPHERE ? "corr" : "flatcorr",
743 >                        sinf->type==SPHERE ? "corr" :
744 >                        !dosides ? "flatcorr" :
745 >                        sinf->type==DISK ? "cylcorr" : "boxcorr",
746                          libname(buf,name,T_DST));
747          if (pmtype == PM_B) {
748                  if (FEQ(bounds[1][0],0.))
# Line 539 | Line 750 | char   *mod, *name;
750                  else
751                          fprintf(out, "srcB_horiz ");
752                  fprintf(out, "srcB_vert ");
753 <        } else {
753 >        } else /* pmtype == PM_A */ {
754                  if (nangles[1] >= 2) {
755                          d1 = bounds[1][1] - bounds[1][0];
756                          if (d1 <= 90.+FTINY)
757                                  fprintf(out, "src_phi4 ");
758 <                        else if (d1 <= 180.+FTINY)
759 <                                fprintf(out, "src_phi2 ");
760 <                        else
758 >                        else if (d1 <= 180.+FTINY) {
759 >                                if (FEQ(bounds[1][0],90.))
760 >                                        fprintf(out, "src_phi2+90 ");
761 >                                else
762 >                                        fprintf(out, "src_phi2 ");
763 >                        } else
764                                  fprintf(out, "src_phi ");
765 <                        fprintf(out, "src_theta -my ");
765 >                        fprintf(out, "src_theta ");
766                          if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
767                                  fprintf(out, "-rz -90 ");
768                  } else
769                          fprintf(out, "src_theta ");
770          }
771 <        fprintf(out, "\n0\n1 %g\n", multiplier*mult*bfactor*pfactor);
772 <        if (putsource(&srcshape, out, id, filename(name),
773 <                        bounds[0][0]<90., bounds[0][1]>90.) != 0)
771 >        if (!dosides || sinf->type == SPHERE)
772 >                fprintf(out, "\n0\n1 %g\n", sinf->mult/sinf->area);
773 >        else if (sinf->type == DISK)
774 >                fprintf(out, "\n0\n3 %g %g %g\n", sinf->mult,
775 >                                sinf->w, sinf->h);
776 >        else
777 >                fprintf(out, "\n0\n4 %g %g %g %g\n", sinf->mult,
778 >                                sinf->l, sinf->w, sinf->h);
779 >        if (putsource(sinf, out, id, filename(name),
780 >                        dolower, doupper, dosides) != 0)
781                  return(-1);
782          return(0);
783   }
784  
785  
786 < putsource(shp, fp, mod, name, dolower, doupper)         /* put out source */
787 < SHAPE   *shp;
788 < FILE    *fp;
789 < char    *mod, *name;
790 < int     dolower, doupper;
786 > int
787 > putsource( /* put out source */
788 >        SRCINFO *shp,
789 >        FILE    *fp,
790 >        char    *mod,
791 >        char    *name,
792 >        int     dolower,
793 >        int     doupper,
794 >        int dosides
795 > )
796   {
797 <        char    buf[MAXWORD];
797 >        char    lname[RMAXWORD];
798          
799 <        fprintf(fp, "\n%s %s %s_light\n", mod,
800 <                        illumrad>=MINDIM/2. ? "illum" : "light",
801 <                        name);
799 >        strcat(strcpy(lname, name), "_light");
800 >        fprintf(fp, "\n%s %s %s\n", mod,
801 >                        shp->isillum ? "illum" : "light", lname);
802          fprintf(fp, "0\n0\n3 %g %g %g\n",
803 <                        lampcolor[0]/shp->area,
578 <                        lampcolor[1]/shp->area,
579 <                        lampcolor[2]/shp->area);
580 <        if (doupper && dolower && shp->type != SPHERE && shp->h > MINDIM) {
581 <                fprintf(fp, "\n%s glow %s_glow\n", mod, name);
582 <                fprintf(fp, "0\n0\n4 %g %g %g 0\n",
583 <                                lampcolor[0]/shp->area,
584 <                                lampcolor[1]/shp->area,
585 <                                lampcolor[2]/shp->area);
586 <        }
803 >                        lampcolor[0], lampcolor[1], lampcolor[2]);
804          switch (shp->type) {
805          case RECT:
589                strcat(strcpy(buf, name), "_light");
806                  if (dolower)
807 <                        putrectsrc(shp, fp, buf, name, 0);
807 >                        putrectsrc(shp, fp, lname, name, 0);
808                  if (doupper)
809 <                        putrectsrc(shp, fp, buf, name, 1);
810 <                if (doupper && dolower && shp->h > MINDIM) {
811 <                        strcat(strcpy(buf, name), "_glow");
596 <                        putsides(shp, fp, buf, name);
597 <                }
809 >                        putrectsrc(shp, fp, lname, name, 1);
810 >                if (dosides)
811 >                        putsides(shp, fp, lname, name);
812                  break;
813          case DISK:
600                strcat(strcpy(buf, name), "_light");
814                  if (dolower)
815 <                        putdisksrc(shp, fp, buf, name, 0);
815 >                        putdisksrc(shp, fp, lname, name, 0);
816                  if (doupper)
817 <                        putdisksrc(shp, fp, buf, name, 1);
818 <                if (doupper && dolower && shp->h > MINDIM) {
819 <                        strcat(strcpy(buf, name), "_glow");
607 <                        putcyl(shp, fp, buf, name);
608 <                }
817 >                        putdisksrc(shp, fp, lname, name, 1);
818 >                if (dosides)
819 >                        putcyl(shp, fp, lname, name);
820                  break;
821          case SPHERE:
822 <                strcat(strcpy(buf, name), "_light");
612 <                putspheresrc(shp, fp, buf, name);
822 >                putspheresrc(shp, fp, lname, name);
823                  break;
824          }
825          return(0);
826   }
827  
828  
829 < makeshape(shp, width, length, height)           /* make source shape */
830 < register SHAPE  *shp;
831 < double  width, length, height;
829 > int
830 > makeshape(              /* make source shape */
831 >        register SRCINFO        *shp,
832 >        double  width,
833 >        double  length,
834 >        double  height
835 > )
836   {
837 <        if (illumrad >= MINDIM/2.) {
837 >        if (illumrad/meters2out >= MINDIM/2.) {
838 >                shp->isillum = 1;
839                  shp->type = SPHERE;
840 <                shp->w = shp->l = shp->h = 2.*illumrad;
840 >                shp->w = shp->l = shp->h = 2.*illumrad / meters2out;
841          } else if (width < MINDIM) {
842                  width = -width;
843                  if (width < MINDIM) {
# Line 656 | Line 871 | double width, length, height;
871                  shp->area = shp->w * shp->l;
872                  break;
873          case DISK:
874 +        case SPHERE:
875                  shp->area = PI/4. * shp->w * shp->w;
876                  break;
661        case SPHERE:
662                shp->area = PI * shp->w * shp->w;
663                break;
877          }
878          return(0);
879   }
880  
881  
882 < putrectsrc(shp, fp, mod, name, up)              /* rectangular source */
883 < SHAPE   *shp;
884 < FILE    *fp;
885 < char    *mod, *name;
886 < int     up;
882 > void
883 > putrectsrc(             /* rectangular source */
884 >        SRCINFO *shp,
885 >        FILE    *fp,
886 >        char    *mod,
887 >        char    *name,
888 >        int     up
889 > )
890   {
891          if (up)
892                  putrect(shp, fp, mod, name, ".u", 4, 5, 7, 6);
# Line 679 | Line 895 | int    up;
895   }
896  
897  
898 < putsides(shp, fp, mod, name)                    /* put out sides of box */
899 < register SHAPE  *shp;
900 < FILE    *fp;
901 < char    *mod, *name;
898 > void
899 > putsides(                       /* put out sides of box */
900 >        register SRCINFO        *shp,
901 >        FILE    *fp,
902 >        char    *mod,
903 >        char    *name
904 > )
905   {
906          putrect(shp, fp, mod, name, ".1", 0, 1, 5, 4);
907          putrect(shp, fp, mod, name, ".2", 1, 3, 7, 5);
# Line 691 | Line 910 | char   *mod, *name;
910   }
911          
912  
913 < putrect(shp, fp, mod, name, suffix, a, b, c, d) /* put out a rectangle */
914 < SHAPE   *shp;
915 < FILE    *fp;
916 < char    *mod, *name, *suffix;
917 < int     a, b, c, d;
913 > void
914 > putrect(        /* put out a rectangle */
915 >        SRCINFO *shp,
916 >        FILE    *fp,
917 >        char    *mod,
918 >        char    *name,
919 >        char    *suffix,
920 >        int     a,
921 >        int b,
922 >        int c,
923 >        int d
924 > )
925   {
926          fprintf(fp, "\n%s polygon %s%s\n0\n0\n12\n", mod, name, suffix);
927          putpoint(shp, fp, a);
# Line 705 | Line 931 | int    a, b, c, d;
931   }
932  
933  
934 < putpoint(shp, fp, p)                            /* put out a point */
935 < register SHAPE  *shp;
936 < FILE    *fp;
937 < int     p;
934 > void
935 > putpoint(                               /* put out a point */
936 >        register SRCINFO        *shp,
937 >        FILE    *fp,
938 >        int     p
939 > )
940   {
941          static double   mult[2] = {-.5, .5};
942  
# Line 719 | Line 947 | int    p;
947   }
948  
949  
950 < putdisksrc(shp, fp, mod, name, up)              /* put out a disk source */
951 < register SHAPE  *shp;
952 < FILE    *fp;
953 < char    *mod, *name;
954 < int     up;
950 > void
951 > putdisksrc(             /* put out a disk source */
952 >        register SRCINFO        *shp,
953 >        FILE    *fp,
954 >        char    *mod,
955 >        char    *name,
956 >        int     up
957 > )
958   {
959          if (up) {
960                  fprintf(fp, "\n%s ring %s.u\n", mod, name);
# Line 741 | Line 972 | int    up;
972   }
973  
974  
975 < putcyl(shp, fp, mod, name)                      /* put out a cylinder */
976 < register SHAPE  *shp;
977 < FILE    *fp;
978 < char    *mod, *name;
975 > void
976 > putcyl(                 /* put out a cylinder */
977 >        register SRCINFO        *shp,
978 >        FILE    *fp,
979 >        char    *mod,
980 >        char    *name
981 > )
982   {
983          fprintf(fp, "\n%s cylinder %s.c\n", mod, name);
984          fprintf(fp, "0\n0\n7\n");
# Line 754 | Line 988 | char   *mod, *name;
988   }
989  
990  
991 < putspheresrc(shp, fp, mod, name)                /* put out a sphere source */
992 < SHAPE   *shp;
993 < FILE    *fp;
994 < char    *mod, *name;
991 > void
992 > putspheresrc(           /* put out a sphere source */
993 >        SRCINFO *shp,
994 >        FILE    *fp,
995 >        char    *mod,
996 >        char    *name
997 > )
998   {
999          fprintf(fp, "\n%s sphere %s.s\n", mod, name);
1000          fprintf(fp, "0\n0\n4 0 0 0 %g\n", .5*shp->w*meters2out);
1001   }
1002  
1003  
1004 < cvdata(in, out, ndim, npts, mult, lim)          /* convert data */
1005 < FILE    *in, *out;
1006 < int     ndim, npts[];
1007 < double  mult, lim[][2];
1004 > int
1005 > cvdata(         /* convert data */
1006 >        FILE    *in,
1007 >        FILE    *out,
1008 >        int     ndim,
1009 >        int     npts[],
1010 >        double  mult,
1011 >        double  lim[][2]
1012 > )
1013   {
1014 <        register double *pt[4];
1014 >        double  *pt[4];
1015          register int    i, j;
1016          double  val;
1017          int     total;
# Line 785 | Line 1027 | double mult, lim[][2];
1027          for (i = 0; i < ndim; i++) {
1028                  pt[i] = (double *)malloc(npts[i]*sizeof(double));
1029                  for (j = 0; j < npts[i]; j++)
1030 <                        fscanf(in, "%lf", &pt[i][j]);
1030 >                        if (!scnflt(in, &pt[i][j]))
1031 >                                return(-1);
1032                  if (lim != NULL) {
1033                          lim[i][0] = pt[i][0];
1034                          lim[i][1] = pt[i][npts[i]-1];
# Line 811 | Line 1054 | double mult, lim[][2];
1054                                  putc('\n', out);
1055                          }
1056                  }
1057 <                free((char *)pt[i]);
1057 >                free((void *)pt[i]);
1058          }
1059          for (i = 0; i < total; i++) {
1060                  if (i%4 == 0)
1061                          putc('\n', out);
1062 <                if (fscanf(in, "%lf", &val) != 1)
1062 >                if (!scnflt(in, &val))
1063                          return(-1);
1064                  fprintf(out, "\t%g", val*mult);
1065          }
1066          putc('\n', out);
1067 +        return(0);
1068 + }
1069 +
1070 +
1071 + char *
1072 + getword(                        /* scan a word from fp */
1073 +        register FILE   *fp
1074 + )
1075 + {
1076 +        static char     wrd[RMAXWORD];
1077 +        register char   *cp;
1078 +        register int    c;
1079 +
1080 +        while (isspace(c=getc(fp)))
1081 +                ;
1082 +        for (cp = wrd; c != EOF && cp < wrd+RMAXWORD-1;
1083 +                        *cp++ = c, c = getc(fp))
1084 +                if (isspace(c) || c == ',') {
1085 +                        while (isspace(c))
1086 +                                c = getc(fp);
1087 +                        if ((c != EOF) & (c != ','))
1088 +                                ungetc(c, fp);
1089 +                        *cp = '\0';
1090 +                        return(wrd);
1091 +                }
1092 +        *cp = '\0';
1093 +        return(cp > wrd ? wrd : NULL);
1094 + }
1095 +
1096 +
1097 + int
1098 + cvtint(                 /* convert a word to an integer */
1099 +        int     *ip,
1100 +        char    *wrd
1101 + )
1102 + {
1103 +        if (wrd == NULL || !isint(wrd))
1104 +                return(0);
1105 +        *ip = atoi(wrd);
1106 +        return(1);
1107 + }
1108 +
1109 +
1110 + int
1111 + cvtflt(                 /* convert a word to a double */
1112 +        double  *rp,
1113 +        char    *wrd
1114 + )
1115 + {
1116 +        if (wrd == NULL || !isflt(wrd))
1117 +                return(0);
1118 +        *rp = atof(wrd);
1119 +        return(1);
1120 + }
1121 +
1122 +
1123 + int
1124 + cvgeometry(
1125 +        char    *inpname,
1126 +        register SRCINFO        *sinf,
1127 +        char    *outname,
1128 +        FILE    *outfp                  /* close output file upon return */
1129 + )
1130 + {
1131 +        char    buf[256];
1132 +        register char   *cp;
1133 +
1134 +        if (inpname == NULL || !inpname[0]) {   /* no geometry file */
1135 +                fclose(outfp);
1136 +                return(0);
1137 +        }
1138 +        putc('\n', outfp);
1139 +        strcpy(buf, "mgf2rad ");                /* build mgf2rad command */
1140 +        cp = buf+8;
1141 +        if (!FEQ(sinf->mult, 1.0)) {
1142 +                sprintf(cp, "-m %f ", sinf->mult);
1143 +                cp += strlen(cp);
1144 +        }
1145 +        sprintf(cp, "-g %f %s ",
1146 +                sqrt(sinf->w*sinf->w + sinf->h*sinf->h + sinf->l*sinf->l),
1147 +                        inpname);
1148 +        cp += strlen(cp);
1149 +        if (instantiate) {              /* instantiate octree */
1150 +                strcpy(cp, "| oconv - > ");
1151 +                cp += 12;
1152 +                fullnam(cp,outname,T_OCT);
1153 +                if (fdate(inpname) > fdate(outname) &&
1154 +                                system(buf)) {          /* create octree */
1155 +                        fclose(outfp);
1156 +                        return(-1);
1157 +                }
1158 +                fprintf(outfp, "void instance %s_inst\n", outname);
1159 +                if (!FEQ(meters2out, 1.0))
1160 +                        fprintf(outfp, "3 %s -s %f\n",
1161 +                                        libname(buf,outname,T_OCT),
1162 +                                        meters2out);
1163 +                else
1164 +                        fprintf(outfp, "1 %s\n", libname(buf,outname,T_OCT));
1165 +                fprintf(outfp, "0\n0\n");
1166 +                fclose(outfp);
1167 +        } else {                        /* else append to luminaire file */
1168 +                if (!FEQ(meters2out, 1.0)) {    /* apply scalefactor */
1169 +                        sprintf(cp, "| xform -s %f ", meters2out);
1170 +                        cp += strlen(cp);
1171 +                }
1172 +                if (!out2stdout) {
1173 +                        fclose(outfp);
1174 +                        strcpy(cp, ">> ");      /* append works for DOS? */
1175 +                        cp += 3;
1176 +                        fullnam(cp,outname,T_RAD);
1177 +                }
1178 +                if (system(buf))
1179 +                        return(-1);
1180 +        }
1181          return(0);
1182   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines