ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/genprism.c
Revision: 2.6
Committed: Tue Mar 19 16:30:56 1996 UTC (28 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +227 -44 lines
Log Message:
added -r option for smoothed edges

File Contents

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