| 20 |
|
* Radiance (θ,φ) luminaire coordinates and then apply photometric and |
| 21 |
|
* tilt data to generate Radiance light. θ is altitude from the |
| 22 |
|
* negative z-axis and φ is azimuth from the positive x-axis, |
| 23 |
< |
* increasing towards the positive y-axis. [??? Greg, is there a |
| 24 |
< |
* source for this convention?] This system matches none of the usual |
| 25 |
< |
* goniophotometric conventions, but it is closest to IES type C; V in |
| 26 |
< |
* type C photometry is θ in Radiance and L is -φ. |
| 23 |
> |
* increasing towards the positive y-axis. This system matches none of |
| 24 |
> |
* the usual goniophotometric conventions, but it is closest to IES |
| 25 |
> |
* type C; V in type C photometry is θ in Radiance and L is -φ. |
| 26 |
|
* |
| 27 |
|
* The ies2rad scene description for a luminaire LUM, with tilt data, |
| 28 |
|
* uses the following Radiance scene description primitives: |
| 69 |
|
* Extensive comments added by Randolph Fritz May2018 |
| 70 |
|
*/ |
| 71 |
|
|
| 73 |
– |
#include <stdio.h> |
| 74 |
– |
#include <string.h> |
| 72 |
|
#include <math.h> |
| 76 |
– |
#include <sys/types.h> |
| 73 |
|
#include <ctype.h> |
| 74 |
|
|
| 75 |
|
#include "rtio.h" |
| 88 |
|
/* Since 1991, LM-63 files have begun with the magic keyword IESNA */ |
| 89 |
|
#define MAGICID "IESNA" |
| 90 |
|
#define LMAGICID 5 |
| 91 |
+ |
/* But newer files start with IESNA:LM-63- */ |
| 92 |
+ |
#define MAGICID2 "IESNA:LM-63-" |
| 93 |
+ |
#define LMAGICID2 12 |
| 94 |
|
/* ies2rad supports the 1986, 1991, and 1995 versions of |
| 95 |
|
* LM-63. FIRSTREV describes the first version; LASTREV describes the |
| 96 |
|
* 1995 version. */ |
| 203 |
|
#define U_METERS 2 |
| 204 |
|
|
| 205 |
|
/* string lengths */ |
| 206 |
< |
/* Maximum input line is 132 characters including CR LF at end. */ |
| 207 |
< |
#define MAXLINE 133 |
| 206 |
> |
/* Maximum input line is 256 characters including CR LF at end. */ |
| 207 |
> |
#define MAXLINE 257 |
| 208 |
|
#define RMAXWORD 76 |
| 209 |
|
|
| 210 |
|
/* End of LM-63-related #defines */ |
| 223 |
|
#define DISK 2 |
| 224 |
|
#define SPHERE 3 |
| 225 |
|
|
| 226 |
< |
/* The diameter of a point source luminaire model. Also the minimum |
| 226 |
> |
/* 1mm. The diameter of a point source luminaire model. Also the minimum |
| 227 |
|
* size (in meters) that the luminous opening of a luminaire must have |
| 228 |
|
* to be treated as other than a point source. */ |
| 229 |
|
#define MINDIM .001 |
| 724 |
|
char *hdl /* header line */ |
| 725 |
|
) |
| 726 |
|
{ |
| 727 |
+ |
/* Skip leading spaces */ |
| 728 |
+ |
while (isspace(*hdl)) |
| 729 |
+ |
hdl++; |
| 730 |
|
/* The line has to begin with '[' */ |
| 731 |
|
if (*hdl++ != '[') |
| 732 |
|
return(0); |
| 842 |
|
continue; |
| 843 |
|
/* increment the header line count, and check for the |
| 844 |
|
* "TILT=" line that terminates the header */ |
| 845 |
< |
if (!lineno++ && strncmp(buf, MAGICID, LMAGICID) == 0) { |
| 846 |
< |
/* This code doesn't work for LM-63-95 and |
| 847 |
< |
* LM-63-02 files and will instead default to |
| 848 |
< |
* LM-63-86. */ |
| 849 |
< |
filerev = atoi(buf+LMAGICID); |
| 845 |
> |
if (!lineno++) { /* first line may be magic */ |
| 846 |
> |
if (!strncmp(buf, MAGICID2, LMAGICID2)) |
| 847 |
> |
filerev = atoi(buf+LMAGICID2) - 1900; |
| 848 |
> |
else if (!strncmp(buf, MAGICID, LMAGICID)) |
| 849 |
> |
filerev = atoi(buf+LMAGICID); |
| 850 |
|
if (filerev < FIRSTREV) |
| 851 |
|
filerev = FIRSTREV; |
| 852 |
|
else if (filerev > LASTREV) |
| 862 |
|
* in the "[LAMP]" and "[LAMPCAT]" keyword lines; |
| 863 |
|
* otherwise check all lines. */ |
| 864 |
|
if (lampcolor == NULL && checklamp(buf)) |
| 865 |
< |
lampcolor = matchlamp( buf[0] == '[' ? |
| 865 |
> |
lampcolor = matchlamp(*sskip2(buf,0) == '[' ? |
| 866 |
|
keyargs(buf) : buf ); |
| 867 |
|
/* Look for a materials and geometry file in the keywords. */ |
| 868 |
|
if (keymatch(K_LMG, buf)) { |
| 883 |
|
} else if (lamptype == NULL) |
| 884 |
|
fprintf(outfp,"# CIE(x,y) = (%f,%f)\n# Depreciation = %.1f%%\n", |
| 885 |
|
lampcolor[3], lampcolor[4], 100.*lampcolor[5]); |
| 886 |
+ |
|
| 887 |
|
/* If the file ended before a "TILT=" line, that's an error. */ |
| 888 |
|
if (feof(inpfp)) { |
| 889 |
|
fprintf(stderr, "%s: not in IES format\n", inpname); |
| 1249 |
|
|
| 1250 |
|
/* makeshape -- decide what shape will be used |
| 1251 |
|
* |
| 1252 |
< |
* makeshape decides what Radiance geometry will be used to represent |
| 1252 |
> |
* Makeshape decides what Radiance geometry will be used to represent |
| 1253 |
|
* the light source and stores information about it in shp. |
| 1254 |
+ |
* |
| 1255 |
+ |
* The various versions of the IES LM-63 standard give a "luminous |
| 1256 |
+ |
* opening" (really a crude shape) a width, a length (or depth), and a |
| 1257 |
+ |
* height. If all three values are positive, they describe a box. If |
| 1258 |
+ |
* they are all zero, they describe a point. Various combinations of |
| 1259 |
+ |
* negative values are used to denote disks, circular or elliptical |
| 1260 |
+ |
* cylinders, spheres, and ellipsoids. This encoding differs from |
| 1261 |
+ |
* version to version of LM-63. |
| 1262 |
+ |
* |
| 1263 |
+ |
* Ies2rad simplifies this, reducing the geometry of LM-63 files to |
| 1264 |
+ |
* three forms which can be easily represented by Radiance primitives: |
| 1265 |
+ |
* boxes (RECT), cylinders or disks (DISK), and spheres (SPHERE.) A |
| 1266 |
+ |
* point is necessarily represented by a small sphere, since a point |
| 1267 |
+ |
* is not a Radiance object. |
| 1268 |
|
*/ |
| 1269 |
|
int |
| 1270 |
|
makeshape( |
| 1276 |
|
{ |
| 1277 |
|
/* Categorize the shape */ |
| 1278 |
|
if (illumrad/meters2out >= MINDIM/2.) { |
| 1279 |
< |
/* If the -i command line option is used, and the |
| 1280 |
< |
* object is not a point source, output an "illum" |
| 1281 |
< |
* sphere */ |
| 1279 |
> |
/* If the -i command line option is used, output an |
| 1280 |
> |
* "illum" sphere whose radius is given by the |
| 1281 |
> |
* argument to -i. */ |
| 1282 |
|
shp->isillum = 1; |
| 1283 |
|
shp->type = SPHERE; |
| 1284 |
|
shp->w = shp->l = shp->h = 2.*illumrad / meters2out; |
| 1285 |
+ |
/* Otherwise, use the dimensions in the IES file */ |
| 1286 |
|
} else if (width < MINDIM) { |
| 1269 |
– |
/* The width is either zero or negative. */ |
| 1287 |
|
width = -width; |
| 1288 |
|
if (width < MINDIM) { |
| 1289 |
< |
/* The width is zero. Use a tiny sphere to |
| 1290 |
< |
* represent a point source. */ |
| 1289 |
> |
/* If the LM-63 width is zero, assume a point |
| 1290 |
> |
* source is described. Output a small |
| 1291 |
> |
* sphere. */ |
| 1292 |
|
shp->type = SPHERE; |
| 1293 |
|
shp->w = shp->l = shp->h = MINDIM; |
| 1294 |
|
} else if (height < .5*width) { |
| 1295 |
|
/* The width is negative and the height is |
| 1296 |
< |
* modest; output either a disk or a thin |
| 1297 |
< |
* vertical cylinder. */ |
| 1296 |
> |
* less than half the width. Treat the |
| 1297 |
> |
* luminous opening as a disk or short |
| 1298 |
> |
* vertical cylinder. Disks will be |
| 1299 |
> |
* represented as nearly flat cylinders of |
| 1300 |
> |
* MINDIM/2 height. */ |
| 1301 |
|
shp->type = DISK; |
| 1302 |
|
shp->w = shp->l = width; |
| 1303 |
|
if (height >= MINDIM) |
| 1305 |
|
else |
| 1306 |
|
shp->h = .5*MINDIM; |
| 1307 |
|
} else { |
| 1308 |
< |
/* The width is negative and the object is |
| 1288 |
< |
* tall; output a sphere. */ |
| 1308 |
> |
/* Treat a tall cylinder as a sphere. */ |
| 1309 |
|
shp->type = SPHERE; |
| 1310 |
|
shp->w = shp->l = shp->h = width; |
| 1311 |
|
} |
| 1312 |
|
} else { |
| 1313 |
< |
/* The width is positive. Output a box, possibly very |
| 1314 |
< |
* thin. */ |
| 1313 |
> |
/* The width is positive. The luminous opening is a |
| 1314 |
> |
box or simple rectangle. */ |
| 1315 |
|
shp->type = RECT; |
| 1316 |
|
shp->w = width; |
| 1317 |
|
if (length >= MINDIM) |