ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/replmarks.c
Revision: 2.7
Committed: Sun Jun 8 12:03:10 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.6: +2 -1 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

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