ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/lampcolor.c
Revision: 2.10
Committed: Thu Mar 18 05:22:00 2004 UTC (20 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.9: +2 -2 lines
Log Message:
Fixed bug caused by substituting fgets() for gets() -- now calls fgetline()

File Contents

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