ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/lampcolor.c
Revision: 2.8
Committed: Sat Jun 21 15:05:01 2003 UTC (20 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.7: +1 -3 lines
Log Message:
Fixed some conflicting definitions

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: lampcolor.c,v 2.7 2003/06/08 12:03:09 schorsch Exp $";
3 #endif
4 /*
5 * Program to convert lamp color from table and compute radiance.
6 */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <math.h>
11
12 #include "standard.h"
13 #include "color.h"
14
15 /* lamp parameters */
16 #define LTYPE 0
17 #define LUNIT 1
18 #define LGEOM 2
19 #define LOUTP 3
20 #define NPARAMS 4
21
22 static int typecheck(char *s);
23 static int unitcheck(char *s);
24 static int geomcheck(char *s);
25 static int outpcheck(char *s);
26 static void compute(void);
27 static int getpolygon(void), getsphere(void), getcylinder(void), getring(void);
28
29
30 float *lampcolor; /* the lamp color (RGB) */
31 double unit2meter; /* conversion from units to meters */
32 double area; /* radiating area for this geometry */
33 double lumens; /* total lamp lumens */
34
35 struct {
36 char *name;
37 char value[64];
38 int (*check)();
39 char *help;
40 } param[NPARAMS] = {
41 { "lamp type", "WHITE", typecheck,
42 "The lamp type is a string which corresponds to one of the types registered\n\
43 in the lamp table file. A value of \"WHITE\" means an uncolored source,\n\
44 which may be preferable because it results in a color balanced image." },
45 { "length unit", "meter", unitcheck,
46 "Unit must be one of: \"meter\", \"centimeter\", \"foot\", or \"inch\".\n\
47 These may be abbreviated as a single letter." },
48 { "lamp geometry", "polygon", geomcheck,
49 "The lamp geometry must be one of: \"polygon\", \"sphere\", \"cylinder\"\n\
50 or \"ring\". These may be abbreviated as a single letter." },
51 { "total lamp lumens", "0", outpcheck,
52 "This is the overall light output of the lamp and its fixture. If you do\n\
53 not know this value explicitly, you can compute the approximate lumens\n\
54 by multiplying the input wattage by 14 for incandescent fixtures or 70\n\
55 for fluorescent fixtures." },
56 };
57
58
59 main(argc, argv)
60 int argc;
61 char *argv[];
62 {
63 char *lamptab = "lamp.tab";
64 char buf[64];
65 int i;
66
67 if (argc > 1) lamptab = argv[1];
68 if (loadlamps(lamptab) == 0) {
69 fprintf(stderr, "%s: no such lamp table\n", lamptab);
70 exit(1);
71 }
72 printf("Program to compute lamp radiance. Enter '?' for help.\n");
73 for ( ; ; ) {
74 i = 0;
75 while (i < NPARAMS) {
76 printf("Enter %s [%s]: ", param[i].name,
77 param[i].value);
78 if (gets(buf) == NULL)
79 exit(0);
80 if (buf[0] == '?') {
81 puts(param[i].help);
82 continue;
83 }
84 if (buf[0])
85 strcpy(param[i].value, buf);
86 if (!(*param[i].check)(param[i].value)) {
87 fprintf(stderr, "%s: bad value for %s\n",
88 param[i].value, param[i].name);
89 continue;
90 }
91 i++;
92 }
93 compute();
94 }
95 }
96
97
98 static int
99 typecheck( /* check lamp type */
100 char *s
101 )
102 {
103 lampcolor = matchlamp(s);
104 return(lampcolor != NULL);
105 }
106
107
108 static int
109 unitcheck( /* compute conversion to meters */
110 char *s
111 )
112 {
113 int len = strlen(s);
114
115 switch (*s) {
116 case 'm':
117 if (strncmp(s, "meters", len))
118 return(0);
119 unit2meter = 1.0;
120 return(1);
121 case 'c':
122 if (strncmp(s, "centimeters", len) && strncmp(s, "cms", len))
123 return(0);
124 unit2meter = 0.01;
125 return(1);
126 case 'f':
127 if (strncmp(s, "foot", len) && strncmp(s, "feet", len))
128 return(0);
129 unit2meter = 0.3048;
130 return(1);
131 case 'i':
132 if (strncmp(s, "inches", len))
133 return(0);
134 unit2meter = 0.0254;
135 return(1);
136 }
137 return(0);
138 }
139
140
141 static int
142 geomcheck( /* check/set lamp geometry */
143 char *s
144 )
145 {
146 int len = strlen(s);
147
148 switch (*s) {
149 case 'p':
150 if (strncmp(s, "polygonal", len))
151 return(0);
152 return(getpolygon());
153 case 's':
154 if (strncmp(s, "sphere", len) && strncmp(s, "spherical", len))
155 return(0);
156 return(getsphere());
157 case 'c':
158 if (strncmp(s,"cylinder",len) && strncmp(s,"cylindrical",len))
159 return(0);
160 return(getcylinder());
161 case 'r':
162 if (strncmp(s, "ring", len) && strncmp(s, "disk", len))
163 return(0);
164 return(getring());
165 }
166 return(0);
167 }
168
169
170 static int
171 outpcheck( /* check lumen output value */
172 register char *s
173 )
174 {
175 if ((*s < '0' || *s > '9') && *s != '.')
176 return(0);
177 lumens = atof(s);
178 return(1);
179 }
180
181
182 static void
183 compute(void) /* compute lamp radiance */
184 {
185 double whiteval;
186
187 whiteval = lumens/area/(WHTEFFICACY*PI);
188
189 printf("Lamp color (RGB) = %f %f %f\n",
190 lampcolor[0]*whiteval,
191 lampcolor[1]*whiteval,
192 lampcolor[2]*whiteval);
193 }
194
195
196 getd(name, dp, help) /* get a positive double from stdin */
197 char *name;
198 double *dp;
199 char *help;
200 {
201 char buf[32];
202 again:
203 printf("%s [%g]: ", name, *dp);
204 if (gets(buf) == NULL)
205 return(0);
206 if (buf[0] == '?') {
207 puts(help);
208 goto again;
209 }
210 if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.')
211 return(0);
212 *dp = atof(buf);
213 return(1);
214 }
215
216
217 static int
218 getpolygon(void) /* get projected area for a polygon */
219 {
220 static double parea = 1.0;
221
222 getd("Polygon area", &parea,
223 "Enter the total radiating area of the polygon.");
224 area = unit2meter*unit2meter * parea;
225 return(1);
226 }
227
228
229 static int
230 getsphere(void) /* get projected area for a sphere */
231 {
232 static double radius = 1.0;
233
234 getd("Sphere radius", &radius,
235 "Enter the distance from the sphere's center to its surface.");
236 area = 4.*PI*unit2meter*unit2meter * radius*radius;
237 return(1);
238 }
239
240
241 static int
242 getcylinder(void) /* get projected area for a cylinder */
243 {
244 static double length = 1.0, radius = 0.1;
245
246 getd("Cylinder length", &length,
247 "Enter the length of the cylinder.");
248 getd("Cylinder radius", &radius,
249 "Enter the distance from the cylinder's axis to its surface.");
250 area = 2.*PI*unit2meter*unit2meter * radius*length;
251 return(1);
252 }
253
254
255 static int
256 getring(void) /* get projected area for a ring */
257 {
258 static double radius = 1.0;
259
260 getd("Disk radius", &radius,
261 "Enter the distance from the ring's center to its outer edge.\n\
262 The inner radius must be zero.");
263 area = PI*unit2meter*unit2meter * radius*radius;
264 return(1);
265 }