ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/replmarks.c
Revision: 1.2
Committed: Mon Feb 18 13:45:12 1991 UTC (33 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +29 -11 lines
Log Message:
added -m option to xform

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1991 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * Replace markers in Radiance scene description with objects or instances.
9     *
10     * Created: 17 Feb 1991 Greg Ward
11     */
12    
13     #include <stdio.h>
14     #include <ctype.h>
15     #include <math.h>
16    
17     #include "fvect.h"
18    
19     #ifdef M_PI
20     #define PI M_PI
21     #else
22     #define PI 3.14159265358979323846
23     #endif
24    
25 greg 1.2 #define FEQ(a,b) ((a)-(b) <= 1e-7 && (b)-(a) <= 1e-7)
26    
27 greg 1.1 #define MAXVERT 6 /* maximum number of vertices for markers */
28    
29     typedef struct {
30     short beg, end; /* beginning and ending vertex */
31     float len2; /* length squared */
32     } EDGE; /* a marker edge */
33    
34     int expand = 0; /* expand commands? */
35    
36 greg 1.2 char *modout = NULL; /* output modifier (for instances) */
37 greg 1.1
38     double markscale = 0.0; /* scale markers by this to get unit */
39    
40     char *modin = NULL; /* input modifier indicating marker */
41    
42     char *objname = NULL; /* output object file (octree if instance) */
43     int doxform; /* true if xform, false if instance */
44    
45     char *progname;
46    
47    
48     main(argc, argv)
49     int argc;
50     char *argv[];
51     {
52     FILE *fp;
53     int i, j;
54    
55     progname = argv[0];
56     for (i = 1; i < argc && argv[i][0] == '-'; i++)
57     switch (argv[i][1]) {
58     case 'i':
59     doxform = 0;
60     objname = argv[++i];
61     break;
62     case 'x':
63     doxform = 1;
64     objname = argv[++i];
65     break;
66     case 'e':
67     expand = !expand;
68     break;
69     case 'm':
70     modout = argv[++i];
71     break;
72     case 's':
73     markscale = atof(argv[++i]);
74     break;
75     default:
76     goto userr;
77     }
78     if (i < argc)
79     modin = argv[i++];
80     if (objname == NULL || modin == NULL)
81     goto userr;
82     /* simple header */
83     putchar('#');
84     for (j = 0; j < i; j++) {
85     putchar(' ');
86     fputs(argv[j], stdout);
87     }
88     putchar('\n');
89     if (i == argc)
90     convert("<stdin>", stdin);
91     else
92     for ( ; i < argc; i++) {
93     if ((fp = fopen(argv[i], "r")) == NULL) {
94     perror(argv[i]);
95     exit(1);
96     }
97     convert(argv[i], fp);
98     fclose(fp);
99     }
100     exit(0);
101     userr:
102     fprintf(stderr,
103     "Usage: %s [-e][-s size][-m modout] {-x objfile|-i octree} modname [file ..]\n",
104     progname);
105     exit(1);
106     }
107    
108    
109     convert(name, fin) /* replace marks in a stream */
110     char *name;
111     register FILE *fin;
112     {
113     register int c;
114    
115     while ((c = getc(fin)) != EOF) {
116     if (isspace(c)) /* blank */
117     continue;
118     if (c == '#') { /* comment */
119     putchar(c);
120     do {
121     if ((c = getc(fin)) == EOF)
122     return;
123     putchar(c);
124     } while (c != '\n');
125     } else if (c == '!') { /* command */
126     ungetc(c, fin);
127     cvcomm(name, fin);
128     } else { /* object */
129     ungetc(c, fin);
130     cvobject(name, fin);
131     }
132     }
133     }
134    
135    
136     cvcomm(fname, fin) /* convert a command */
137     char *fname;
138     FILE *fin;
139     {
140     FILE *pin, *popen();
141     char buf[512], *fgetline();
142    
143     fgetline(buf, sizeof(buf), fin);
144     if (expand) {
145     if ((pin = popen(buf+1, "r")) == NULL) {
146     fprintf(stderr,
147     "%s: (%s): cannot execute \"%s\"\n",
148     progname, fname, buf);
149     exit(1);
150     }
151     convert(buf, pin);
152     pclose(pin);
153     } else
154     printf("\n%s\n", buf);
155     }
156    
157    
158     cvobject(fname, fin) /* convert an object */
159     char *fname;
160     FILE *fin;
161     {
162     char buf[128], typ[16], nam[128];
163     int i, j, n;
164    
165     if (fscanf(fin, "%s %s %s", buf, typ, nam) != 3)
166     goto readerr;
167     if (!strcmp(buf, modin) && !strcmp(typ, "polygon")) {
168     replace(fname, nam, fin);
169     return;
170     }
171     printf("\n%s %s %s\n", buf, typ, nam);
172     if (!strcmp(typ, "alias")) { /* alias special case */
173     if (fscanf(fin, "%s", buf) != 1)
174     goto readerr;
175     printf("\t%s\n", buf);
176     return;
177     }
178     for (i = 0; i < 3; i++) { /* pass along arguments */
179     if (fscanf(fin, "%d", &n) != 1)
180     goto readerr;
181     printf("%d", n);
182     for (j = 0; j < n; j++) {
183     if (fscanf(fin, "%s", buf) != 1)
184     goto readerr;
185     if (j%3 == 0)
186     putchar('\n');
187     printf("\t%s", buf);
188     }
189     putchar('\n');
190     }
191     return;
192     readerr:
193     fprintf(stderr, "%s: (%s): read error for %s \"%s\"\n",
194     progname, fname, typ, nam);
195     }
196    
197    
198     replace(fname, mark, fin) /* replace marker */
199     char *fname, *mark;
200     FILE *fin;
201     {
202     int n;
203     char buf[256];
204    
205     if (doxform) {
206     sprintf(buf, "xform -e -n %s", mark);
207 greg 1.2 if (modout != NULL)
208     sprintf(buf+strlen(buf), " -m %s", modout);
209 greg 1.1 if (buildxf(buf+strlen(buf), fin) < 0)
210     goto badxf;
211     sprintf(buf+strlen(buf), " %s", objname);
212     if (expand) {
213     fflush(stdout);
214     system(buf);
215     } else
216     printf("\n!%s\n", buf);
217     } else {
218     if ((n = buildxf(buf, fin)) < 0)
219     goto badxf;
220 greg 1.2 printf("\n%s instance %s\n", modout==NULL?"void":modout, mark);
221     printf("%d %s%s\n0\n0\n", n+1, objname, buf);
222 greg 1.1 }
223     return;
224     badxf:
225     fprintf(stderr, "%s: (%s): bad arguments for marker \"%s\"\n",
226     progname, fname, mark);
227     exit(1);
228     }
229    
230    
231     edgecmp(e1, e2) /* compare two edges, descending order */
232     EDGE *e1, *e2;
233     {
234     if (e1->len2 > e2->len2)
235     return(-1);
236     if (e1->len2 < e2->len2)
237     return(1);
238     return(0);
239     }
240    
241    
242     int
243     buildxf(xf, fin) /* build transform for marker */
244     char *xf;
245     FILE *fin;
246     {
247     static FVECT vlist[MAXVERT];
248     static EDGE elist[MAXVERT];
249     FVECT xvec, yvec, zvec;
250     double xlen;
251     int n;
252     register int i;
253     /*
254     * Read and sort vectors: longest is hypotenuse,
255     * second longest is x' axis,
256     * third longest is y' axis (approximate),
257     * other vectors are ignored.
258     * It is an error if the x' and y' axes do
259     * not share a common vertex (their origin).
260     */
261     if (fscanf(fin, "%*d %*d %d", &n) != 1)
262     return(-1);
263     if (n%3 != 0)
264     return(-1);
265     n /= 3;
266     if (n < 3 || n > MAXVERT)
267     return(-1);
268     /* sort edges in descending order */
269     for (i = 0; i < n; i++) {
270     if (fscanf(fin, "%lf %lf %lf", &vlist[i][0],
271     &vlist[i][1], &vlist[i][2]) != 3)
272     return(-1);
273     if (i) {
274     elist[i].beg = i-1;
275     elist[i].end = i;
276     elist[i].len2 = dist2(vlist[i-1],vlist[i]);
277     }
278     }
279     elist[0].beg = n-1;
280     elist[0].end = 0;
281     elist[0].len2 = dist2(vlist[n-1],vlist[0]);
282     qsort(elist, n, sizeof(EDGE), edgecmp);
283     /* find x' and y' */
284     if (elist[1].end == elist[2].beg || elist[1].end == elist[2].end) {
285     i = elist[1].beg;
286     elist[1].beg = elist[1].end;
287     elist[1].end = i;
288     }
289     if (elist[2].end == elist[1].beg) {
290     i = elist[2].beg;
291     elist[2].beg = elist[2].end;
292     elist[2].end = i;
293     }
294     if (elist[1].beg != elist[2].beg)
295     return(-1); /* x' and y' not connected! */
296     for (i = 0; i < 3; i++) {
297     xvec[i] = vlist[elist[1].end][i] - vlist[elist[1].beg][i];
298     yvec[i] = vlist[elist[2].end][i] - vlist[elist[2].beg][i];
299     }
300     if ((xlen = normalize(xvec)) == 0.0)
301     return(-1);
302     fcross(zvec, xvec, yvec);
303     if (normalize(zvec) == 0.0)
304     return(-1);
305     fcross(yvec, zvec, xvec);
306     n = 0; /* start transformation... */
307     if (markscale > 0.0) { /* add scale factor */
308     sprintf(xf, " -s %f", xlen*markscale);
309     n += 2;
310     xf += strlen(xf);
311     }
312     /* add rotation */
313     n += addrot(xf, xvec, yvec, zvec);
314     xf += strlen(xf);
315     /* add translation */
316     n += 4;
317     sprintf(xf, " -t %f %f %f", vlist[elist[1].beg][0],
318     vlist[elist[1].beg][1], vlist[elist[1].beg][2]);
319     return(n); /* all done */
320     }
321    
322    
323     addrot(xf, xp, yp, zp) /* compute rotation (x,y,z) => (xp,yp,zp) */
324     char *xf;
325     FVECT xp, yp, zp;
326     {
327 greg 1.2 int n;
328     double theta;
329 greg 1.1
330 greg 1.2 n = 0;
331     theta = atan2(yp[2], zp[2]);
332     if (!FEQ(theta,0.0)) {
333     sprintf(xf, " -rx %f", theta*(180./PI));
334     xf += strlen(xf);
335     n += 2;
336     }
337     theta = asin(-xp[2]);
338     if (!FEQ(theta,0.0)) {
339     sprintf(xf, " -ry %f", theta*(180./PI));
340     xf += strlen(xf);
341     n += 2;
342     }
343     theta = atan2(xp[1], xp[0]);
344     if (!FEQ(theta,0.0)) {
345     sprintf(xf, " -rz %f", theta*(180./PI));
346     /* xf += strlen(xf); */
347     n += 2;
348     }
349     return(n);
350 greg 1.1 }