ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.8
Committed: Sat Feb 22 02:07:23 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.7: +3 -8 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * genprism.c - generate a prism.
6 * 2D vertices in the xy plane are given on the
7 * command line or from a file. Their order together
8 * with the extrude direction will determine surface
9 * orientation.
10 */
11
12 #include <stdio.h>
13
14 #include <stdlib.h>
15
16 #include <math.h>
17
18 #include <ctype.h>
19
20 #define MAXVERT 1024 /* maximum # vertices */
21
22 #define FTINY 1e-6
23
24 char *pmtype; /* material type */
25 char *pname; /* name */
26
27 double lvect[3] = {0.0, 0.0, 1.0};
28 int lvdir = 1;
29 double llen = 1.0;
30
31 double vert[MAXVERT][2];
32 int nverts = 0;
33
34 double u[MAXVERT][2]; /* edge unit vectors */
35 double a[MAXVERT]; /* corner trim sizes */
36
37 int do_ends = 1; /* include end caps */
38 int iscomplete = 0; /* polygon is already completed */
39 double crad = 0.0; /* radius for corners (sign from lvdir) */
40
41 extern double compute_rounding();
42
43
44 main(argc, argv)
45 int argc;
46 char **argv;
47 {
48 int an;
49
50 if (argc < 4)
51 goto userr;
52
53 pmtype = argv[1];
54 pname = argv[2];
55
56 if (!strcmp(argv[3], "-")) {
57 readverts(NULL);
58 an = 4;
59 } else if (isdigit(argv[3][0])) {
60 nverts = atoi(argv[3]);
61 if (argc-3 < 2*nverts)
62 goto userr;
63 for (an = 0; an < nverts; an++) {
64 vert[an][0] = atof(argv[2*an+4]);
65 vert[an][1] = atof(argv[2*an+5]);
66 }
67 an = 2*nverts+4;
68 } else {
69 readverts(argv[3]);
70 an = 4;
71 }
72 if (nverts < 3) {
73 fprintf(stderr, "%s: not enough vertices\n", argv[0]);
74 exit(1);
75 }
76
77 for ( ; an < argc; an++) {
78 if (argv[an][0] != '-')
79 goto userr;
80 switch (argv[an][1]) {
81 case 'l': /* length vector */
82 lvect[0] = atof(argv[++an]);
83 lvect[1] = atof(argv[++an]);
84 lvect[2] = atof(argv[++an]);
85 if (lvect[2] < -FTINY)
86 lvdir = -1;
87 else if (lvect[2] > FTINY)
88 lvdir = 1;
89 else {
90 fprintf(stderr,
91 "%s: illegal extrusion vector\n",
92 argv[0]);
93 exit(1);
94 }
95 llen = sqrt(lvect[0]*lvect[0] + lvect[1]*lvect[1] +
96 lvect[2]*lvect[2]);
97 break;
98 case 'r': /* radius */
99 crad = atof(argv[++an]);
100 break;
101 case 'e': /* ends */
102 do_ends = !do_ends;
103 break;
104 case 'c': /* complete */
105 iscomplete = !iscomplete;
106 break;
107 default:
108 goto userr;
109 }
110 }
111 if (crad > FTINY) {
112 if (crad > lvdir*lvect[2]) {
113 fprintf(stderr, "%s: rounding greater than height\n",
114 argv[0]);
115 exit(1);
116 }
117 crad *= lvdir; /* simplifies formulas */
118 compute_rounding();
119 printhead(argc, argv);
120 if (do_ends)
121 printrends();
122 printsides(1);
123 } else {
124 printhead(argc, argv);
125 if (do_ends)
126 printends();
127 printsides(0);
128 }
129 exit(0);
130 userr:
131 fprintf(stderr, "Usage: %s material name ", argv[0]);
132 fprintf(stderr, "{ - | vfile | N v1 v2 .. vN } ");
133 fprintf(stderr, "[-l lvect][-r radius][-c][-e]\n");
134 exit(1);
135 }
136
137
138 readverts(fname) /* read vertices from a file */
139 char *fname;
140 {
141 FILE *fp;
142
143 if (fname == NULL)
144 fp = stdin;
145 else if ((fp = fopen(fname, "r")) == NULL) {
146 fprintf(stderr, "%s: cannot open\n", fname);
147 exit(1);
148 }
149 while (fscanf(fp, "%lf %lf", &vert[nverts][0], &vert[nverts][1]) == 2)
150 nverts++;
151 fclose(fp);
152 }
153
154
155 double
156 compute_rounding() /* compute vectors for rounding operations */
157 {
158 register int i;
159 register double *v0, *v1;
160 double l, asum;
161
162 v0 = vert[nverts-1];
163 for (i = 0; i < nverts; i++) { /* compute u[*] */
164 v1 = vert[i];
165 u[i][0] = v0[0] - v1[0];
166 u[i][1] = v0[1] - v1[1];
167 l = sqrt(u[i][0]*u[i][0] + u[i][1]*u[i][1]);
168 if (l <= FTINY) {
169 fprintf(stderr, "Degenerate side in prism\n");
170 exit(1);
171 }
172 u[i][0] /= l;
173 u[i][1] /= l;
174 v0 = v1;
175 }
176 asum = 0.;
177 v1 = u[0];
178 for (i = nverts; i--; ) { /* compute a[*] */
179 v0 = u[i];
180 l = v0[0]*v1[0] + v0[1]*v1[1];
181 if (1+l <= FTINY) {
182 fprintf(stderr, "Overlapping sides in prism\n");
183 exit(1);
184 }
185 if (1-l <= 0.)
186 a[i] = 0.;
187 else {
188 a[i] = sqrt((1-l)/(1+l));
189 asum += l = v1[0]*v0[1]-v1[1]*v0[0];
190 if (l < 0.)
191 a[i] = -a[i];
192 }
193 v1 = v0;
194 }
195 return(asum*.5);
196 }
197
198
199 printends() /* print ends of prism */
200 {
201 register int i;
202 /* bottom face */
203 printf("\n%s polygon %s.b\n", pmtype, pname);
204 printf("0\n0\n%d\n", nverts*3);
205 for (i = 0; i < nverts; i++)
206 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0],
207 vert[i][1], 0.0);
208 /* top face */
209 printf("\n%s polygon %s.t\n", pmtype, pname);
210 printf("0\n0\n%d\n", nverts*3);
211 for (i = nverts; i--; )
212 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[i][0]+lvect[0],
213 vert[i][1]+lvect[1], lvect[2]);
214 }
215
216
217 printrends() /* print ends of prism with rounding */
218 {
219 register int i;
220 double c0[3], c1[3], cl[3];
221 /* bottom face */
222 printf("\n%s polygon %s.b\n", pmtype, pname);
223 printf("0\n0\n%d\n", nverts*3);
224 for (i = 0; i < nverts; i++) {
225 printf("\t%18.12g\t%18.12g\t%18.12g\n",
226 vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]),
227 vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]),
228 0.0);
229 }
230 /* top face */
231 printf("\n%s polygon %s.t\n", pmtype, pname);
232 printf("0\n0\n%d\n", nverts*3);
233 for (i = nverts; i--; ) {
234 printf("\t%18.12g\t%18.12g\t%18.12g\n",
235 vert[i][0] + lvect[0] + crad*(a[i]*u[i][0] - u[i][1]),
236 vert[i][1] + lvect[1] + crad*(a[i]*u[i][1] + u[i][0]),
237 lvect[2]);
238 }
239 /* bottom corners and edges */
240 c0[0] = cl[0] = vert[nverts-1][0] +
241 crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
242 c0[1] = cl[1] = vert[nverts-1][1] +
243 crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
244 c0[2] = cl[2] = crad;
245 for (i = 0; i < nverts; i++) {
246 if (i < nverts-1) {
247 c1[0] = vert[i][0] + crad*(a[i]*u[i][0] - u[i][1]);
248 c1[1] = vert[i][1] + crad*(a[i]*u[i][1] + u[i][0]);
249 c1[2] = crad;
250 } else {
251 c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
252 }
253 if (lvdir*a[i] > 0.) {
254 printf("\n%s sphere %s.bc%d\n", pmtype, pname, i+1);
255 printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
256 c1[0], c1[1], c1[2], lvdir*crad);
257 }
258 printf("\n%s cylinder %s.be%d\n", pmtype, pname, i+1);
259 printf("0\n0\n7\n");
260 printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
261 printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
262 printf("\t%18.12g\n", lvdir*crad);
263 c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
264 }
265 /* top corners and edges */
266 c0[0] = cl[0] = vert[nverts-1][0] + lvect[0] +
267 crad*(a[nverts-1]*u[nverts-1][0] - u[nverts-1][1]);
268 c0[1] = cl[1] = vert[nverts-1][1] + lvect[1] +
269 crad*(a[nverts-1]*u[nverts-1][1] + u[nverts-1][0]);
270 c0[2] = cl[2] = lvect[2] - crad;
271 for (i = 0; i < nverts; i++) {
272 if (i < nverts-1) {
273 c1[0] = vert[i][0] + lvect[0] +
274 crad*(a[i]*u[i][0] - u[i][1]);
275 c1[1] = vert[i][1] + lvect[1] +
276 crad*(a[i]*u[i][1] + u[i][0]);
277 c1[2] = lvect[2] - crad;
278 } else {
279 c1[0] = cl[0]; c1[1] = cl[1]; c1[2] = cl[2];
280 }
281 if (lvdir*a[i] > 0.) {
282 printf("\n%s sphere %s.tc%d\n", pmtype, pname, i+1);
283 printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
284 c1[0], c1[1], c1[2], lvdir*crad);
285 }
286 printf("\n%s cylinder %s.te%d\n", pmtype, pname, i+1);
287 printf("0\n0\n7\n");
288 printf("\t%18.12g\t%18.12g\t%18.12g\n", c0[0], c0[1], c0[2]);
289 printf("\t%18.12g\t%18.12g\t%18.12g\n", c1[0], c1[1], c1[2]);
290 printf("\t%18.12g\n", lvdir*crad);
291 c0[0] = c1[0]; c0[1] = c1[1]; c0[2] = c1[2];
292 }
293 }
294
295
296 printsides(round) /* print prism sides */
297 int round;
298 {
299 register int i;
300
301 for (i = 0; i < nverts-1; i++)
302 if (round)
303 rside(i, i+1);
304 else
305 side(i, i+1);
306 if (!iscomplete)
307 if (round)
308 rside(nverts-1, 0);
309 else
310 side(nverts-1, 0);
311 }
312
313
314 side(n0, n1) /* print single side */
315 register int n0, n1;
316 {
317 printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
318 printf("0\n0\n12\n");
319 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0],
320 vert[n0][1], 0.0);
321 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n0][0]+lvect[0],
322 vert[n0][1]+lvect[1], lvect[2]);
323 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0]+lvect[0],
324 vert[n1][1]+lvect[1], lvect[2]);
325 printf("\t%18.12g\t%18.12g\t%18.12g\n", vert[n1][0],
326 vert[n1][1], 0.0);
327 }
328
329
330 rside(n0, n1) /* print side with rounded edge */
331 register int n0, n1;
332 {
333 double s, c, t[3];
334
335 /* compute tanget offset vector */
336 s = lvdir*(lvect[1]*u[n1][0] - lvect[0]*u[n1][1])/llen;
337 if (s < -FTINY || s > FTINY) {
338 c = sqrt(1. - s*s);
339 t[0] = (c - 1.)*u[n1][1];
340 t[1] = (1. - c)*u[n1][0];
341 t[2] = s;
342 } else
343 t[0] = t[1] = t[2] = 0.;
344 /* output side */
345 printf("\n%s polygon %s.%d\n", pmtype, pname, n0+1);
346 printf("0\n0\n12\n");
347 printf("\t%18.12g\t%18.12g\t%18.12g\n",
348 vert[n0][0] + crad*(t[0] - a[n0]*u[n1][0]),
349 vert[n0][1] + crad*(t[1] - a[n0]*u[n1][1]),
350 crad*(t[2] + 1.));
351 printf("\t%18.12g\t%18.12g\t%18.12g\n",
352 vert[n0][0] + lvect[0] + crad*(t[0] - a[n0]*u[n1][0]),
353 vert[n0][1] + lvect[1] + crad*(t[1] - a[n0]*u[n1][1]),
354 lvect[2] + crad*(t[2] - 1.));
355 printf("\t%18.12g\t%18.12g\t%18.12g\n",
356 vert[n1][0] + lvect[0] + crad*(t[0] + a[n1]*u[n1][0]),
357 vert[n1][1] + lvect[1] + crad*(t[1] + a[n1]*u[n1][1]),
358 lvect[2] + crad*(t[2] - 1.));
359 printf("\t%18.12g\t%18.12g\t%18.12g\n",
360 vert[n1][0] + crad*(t[0] + a[n1]*u[n1][0]),
361 vert[n1][1] + crad*(t[1] + a[n1]*u[n1][1]),
362 crad*(t[2] + 1.));
363 /* output joining edge */
364 if (lvdir*a[n1] < 0.)
365 return;
366 printf("\n%s cylinder %s.e%d\n", pmtype, pname, n0+1);
367 printf("0\n0\n7\n");
368 printf("\t%18.12g\t%18.12g\t%18.12g\n",
369 vert[n1][0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
370 vert[n1][1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
371 crad);
372 printf("\t%18.12g\t%18.12g\t%18.12g\n",
373 vert[n1][0] + lvect[0] + crad*(a[n1]*u[n1][0] - u[n1][1]),
374 vert[n1][1] + lvect[1] + crad*(a[n1]*u[n1][1] + u[n1][0]),
375 lvect[2] - crad);
376 printf("\t%18.12g\n", lvdir*crad);
377 }
378
379
380 printhead(ac, av) /* print command header */
381 register int ac;
382 register char **av;
383 {
384 putchar('#');
385 while (ac--) {
386 putchar(' ');
387 fputs(*av++, stdout);
388 }
389 putchar('\n');
390 }