ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtmain.c
Revision: 2.4
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.3: +8 -11 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rtmain.c,v 2.3 2003/05/13 17:58:33 greg Exp $";
3 #endif
4 /*
5 * rtmain.c - main for rtrace per-ray calculation program
6 */
7
8 #include "copyright.h"
9
10 #include <sys/types.h>
11 #include <signal.h>
12
13 #include "platform.h"
14 #include "ray.h"
15 #include "source.h"
16 #include "ambient.h"
17 #include "random.h"
18 #include "paths.h"
19
20 /* persistent processes define */
21 #ifdef F_SETLKW
22 #define PERSIST 1 /* normal persist */
23 #define PARALLEL 2 /* parallel persist */
24 #define PCHILD 3 /* child of normal persist */
25 #endif
26
27 char *progname; /* argv[0] */
28
29 char *octname; /* octree name */
30
31 char *sigerr[NSIG]; /* signal error messages */
32
33 char *shm_boundary = NULL; /* boundary of shared memory */
34
35 char *errfile = NULL; /* error output file */
36
37 extern char *formstr(); /* string from format */
38 extern int inform; /* input format */
39 extern int outform; /* output format */
40 extern char *outvals; /* output values */
41
42 extern int hresolu; /* horizontal resolution */
43 extern int vresolu; /* vertical resolution */
44
45 extern int imm_irrad; /* compute immediate irradiance? */
46 extern int lim_dist; /* limit distance? */
47
48 extern char *tralist[]; /* list of modifers to trace (or no) */
49 extern int traincl; /* include == 1, exclude == 0 */
50
51 void onsig();
52 void sigdie();
53 void printdefaults();
54
55
56 int
57 main(argc, argv)
58 int argc;
59 char *argv[];
60 {
61 #define check(ol,al) if (argv[i][ol] || \
62 badarg(argc-i-1,argv+i+1,al)) \
63 goto badopt
64 #define bool(olen,var) switch (argv[i][olen]) { \
65 case '\0': var = !var; break; \
66 case 'y': case 'Y': case 't': case 'T': \
67 case '+': case '1': var = 1; break; \
68 case 'n': case 'N': case 'f': case 'F': \
69 case '-': case '0': var = 0; break; \
70 default: goto badopt; }
71 int loadflags = ~IO_FILES;
72 int persist = 0;
73 char **tralp;
74 int duped1;
75 int rval;
76 int i;
77 /* global program name */
78 progname = argv[0] = fixargv0(argv[0]);
79 /* option city */
80 for (i = 1; i < argc; i++) {
81 /* expand arguments */
82 while ((rval = expandarg(&argc, &argv, i)) > 0)
83 ;
84 if (rval < 0) {
85 sprintf(errmsg, "cannot expand '%s'", argv[i]);
86 error(SYSTEM, errmsg);
87 }
88 if (argv[i] == NULL || argv[i][0] != '-')
89 break; /* break from options */
90 if (!strcmp(argv[i], "-version")) {
91 puts(VersionID);
92 quit(0);
93 }
94 if (!strcmp(argv[i], "-defaults") ||
95 !strcmp(argv[i], "-help")) {
96 printdefaults();
97 quit(0);
98 }
99 rval = getrenderopt(argc-i, argv+i);
100 if (rval >= 0) {
101 i += rval;
102 continue;
103 }
104 switch (argv[i][1]) {
105 case 'x': /* x resolution */
106 check(2,"i");
107 hresolu = atoi(argv[++i]);
108 break;
109 case 'y': /* y resolution */
110 check(2,"i");
111 vresolu = atoi(argv[++i]);
112 break;
113 case 'w': /* warnings */
114 rval = erract[WARNING].pf != NULL;
115 bool(2,rval);
116 if (rval) erract[WARNING].pf = wputs;
117 else erract[WARNING].pf = NULL;
118 break;
119 case 'e': /* error file */
120 check(2,"s");
121 errfile = argv[++i];
122 break;
123 case 'l': /* limit distance */
124 if (argv[i][2] != 'd')
125 goto badopt;
126 bool(3,lim_dist);
127 break;
128 case 'I': /* immed. irradiance */
129 bool(2,imm_irrad);
130 break;
131 case 'f': /* format i/o */
132 switch (argv[i][2]) {
133 case 'a': /* ascii */
134 case 'f': /* float */
135 case 'd': /* double */
136 inform = argv[i][2];
137 break;
138 default:
139 goto badopt;
140 }
141 switch (argv[i][3]) {
142 case '\0':
143 outform = inform;
144 break;
145 case 'a': /* ascii */
146 case 'f': /* float */
147 case 'd': /* double */
148 case 'c': /* color */
149 check(4,"");
150 outform = argv[i][3];
151 break;
152 default:
153 goto badopt;
154 }
155 break;
156 case 'o': /* output */
157 outvals = argv[i]+2;
158 break;
159 case 'h': /* header output */
160 rval = loadflags & IO_INFO;
161 bool(2,rval);
162 loadflags = rval ? loadflags | IO_INFO :
163 loadflags & ~IO_INFO;
164 break;
165 case 't': /* trace */
166 switch (argv[i][2]) {
167 case 'i': /* include */
168 case 'I':
169 check(3,"s");
170 if (traincl != 1) {
171 traincl = 1;
172 tralp = tralist;
173 }
174 if (argv[i][2] == 'I') { /* file */
175 rval = wordfile(tralp,
176 getpath(argv[++i],getrlibpath(),R_OK));
177 if (rval < 0) {
178 sprintf(errmsg,
179 "cannot open trace include file \"%s\"",
180 argv[i]);
181 error(SYSTEM, errmsg);
182 }
183 tralp += rval;
184 } else {
185 *tralp++ = argv[++i];
186 *tralp = NULL;
187 }
188 break;
189 case 'e': /* exclude */
190 case 'E':
191 check(3,"s");
192 if (traincl != 0) {
193 traincl = 0;
194 tralp = tralist;
195 }
196 if (argv[i][2] == 'E') { /* file */
197 rval = wordfile(tralp,
198 getpath(argv[++i],getrlibpath(),R_OK));
199 if (rval < 0) {
200 sprintf(errmsg,
201 "cannot open trace exclude file \"%s\"",
202 argv[i]);
203 error(SYSTEM, errmsg);
204 }
205 tralp += rval;
206 } else {
207 *tralp++ = argv[++i];
208 *tralp = NULL;
209 }
210 break;
211 default:
212 goto badopt;
213 }
214 break;
215 #ifdef PERSIST
216 case 'P': /* persist file */
217 if (argv[i][2] == 'P') {
218 check(3,"s");
219 persist = PARALLEL;
220 } else {
221 check(2,"s");
222 persist = PERSIST;
223 }
224 persistfile(argv[++i]);
225 break;
226 #endif
227 default:
228 goto badopt;
229 }
230 }
231 /* initialize object types */
232 initotypes();
233 /* initialize urand */
234 initurand(2048);
235 /* set up signal handling */
236 sigdie(SIGINT, "Interrupt");
237 sigdie(SIGHUP, "Hangup");
238 sigdie(SIGTERM, "Terminate");
239 sigdie(SIGPIPE, "Broken pipe");
240 sigdie(SIGALRM, "Alarm clock");
241 #ifdef SIGXCPU
242 sigdie(SIGXCPU, "CPU limit exceeded");
243 sigdie(SIGXFSZ, "File size exceeded");
244 #endif
245 /* open error file */
246 if (errfile != NULL) {
247 if (freopen(errfile, "a", stderr) == NULL)
248 quit(2);
249 fprintf(stderr, "**************\n*** PID %5d: ",
250 getpid());
251 printargs(argc, argv, stderr);
252 putc('\n', stderr);
253 fflush(stderr);
254 }
255 #ifdef NICE
256 nice(NICE); /* lower priority */
257 #endif
258 /* get octree */
259 if (i == argc)
260 octname = NULL;
261 else if (i == argc-1)
262 octname = argv[i];
263 else
264 goto badopt;
265 if (octname == NULL)
266 error(USER, "missing octree argument");
267 /* set up output */
268 #ifdef PERSIST
269 if (persist) {
270 duped1 = dup(fileno(stdout)); /* don't lose our output */
271 openheader();
272 }
273 #endif
274 #ifdef _WIN32
275 if (outform != 'a')
276 SET_FILE_BINARY(stdout);
277 if (octname == NULL)
278 SET_FILE_BINARY(stdin);
279 #endif
280 readoct(octname, loadflags, &thescene, NULL);
281 nsceneobjs = nobjects;
282
283 if (loadflags & IO_INFO) { /* print header */
284 printargs(i, argv, stdout);
285 printf("SOFTWARE= %s\n", VersionID);
286 fputnow(stdout);
287 fputformat(formstr(outform), stdout);
288 putchar('\n');
289 }
290
291 marksources(); /* find and mark sources */
292
293 setambient(); /* initialize ambient calculation */
294
295 #ifdef PERSIST
296 if (persist) {
297 fflush(stdout);
298 /* reconnect stdout */
299 dup2(duped1, fileno(stdout));
300 close(duped1);
301 if (persist == PARALLEL) { /* multiprocessing */
302 preload_objs(); /* preload scene */
303 shm_boundary = (char *)malloc(16);
304 strcpy(shm_boundary, "SHM_BOUNDARY");
305 while ((rval=fork()) == 0) { /* keep on forkin' */
306 pflock(1);
307 pfhold();
308 }
309 if (rval < 0)
310 error(SYSTEM, "cannot fork child for persist function");
311 pfdetach(); /* parent exits */
312 }
313 }
314 runagain:
315 if (persist)
316 dupheader(); /* send header to stdout */
317 #endif
318 /* trace rays */
319 rtrace(NULL);
320 /* flush ambient file */
321 ambsync();
322 #ifdef PERSIST
323 if (persist == PERSIST) { /* first run-through */
324 if ((rval=fork()) == 0) { /* child loops until killed */
325 pflock(1);
326 persist = PCHILD;
327 } else { /* original process exits */
328 if (rval < 0)
329 error(SYSTEM, "cannot fork child for persist function");
330 pfdetach(); /* parent exits */
331 }
332 }
333 if (persist == PCHILD) { /* wait for a signal then go again */
334 close(duped1); /* release output handle */
335 pfhold();
336 raynum = nrays = 0; /* reinitialize */
337 goto runagain;
338 }
339 #endif
340 quit(0);
341
342 badopt:
343 sprintf(errmsg, "command line error at '%s'", argv[i]);
344 error(USER, errmsg);
345
346 #undef check
347 #undef bool
348 }
349
350
351 void
352 wputs(s) /* warning output function */
353 char *s;
354 {
355 int lasterrno = errno;
356 eputs(s);
357 errno = lasterrno;
358 }
359
360
361 void
362 eputs(s) /* put string to stderr */
363 register char *s;
364 {
365 static int midline = 0;
366
367 if (!*s)
368 return;
369 if (!midline++) {
370 fputs(progname, stderr);
371 fputs(": ", stderr);
372 }
373 fputs(s, stderr);
374 if (s[strlen(s)-1] == '\n') {
375 fflush(stderr);
376 midline = 0;
377 }
378 }
379
380
381 void
382 onsig(signo) /* fatal signal */
383 int signo;
384 {
385 static int gotsig = 0;
386
387 if (gotsig++) /* two signals and we're gone! */
388 _exit(signo);
389
390 alarm(15); /* allow 15 seconds to clean up */
391 signal(SIGALRM, SIG_DFL); /* make certain we do die */
392 eputs("signal - ");
393 eputs(sigerr[signo]);
394 eputs("\n");
395 quit(3);
396 }
397
398
399 void
400 sigdie(signo, msg) /* set fatal signal */
401 int signo;
402 char *msg;
403 {
404 if (signal(signo, onsig) == SIG_IGN)
405 signal(signo, SIG_IGN);
406 sigerr[signo] = msg;
407 }
408
409
410 void
411 printdefaults() /* print default values to stdout */
412 {
413 register char *cp;
414
415 if (imm_irrad)
416 printf("-I+\t\t\t\t# immediate irradiance on\n");
417 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
418 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
419 printf(lim_dist ? "-ld+\t\t\t\t# limit distance on\n" :
420 "-ld-\t\t\t\t# limit distance off\n");
421 printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
422 inform, outform, formstr(inform), formstr(outform));
423 printf("-o%s\t\t\t\t# output", outvals);
424 for (cp = outvals; *cp; cp++)
425 switch (*cp) {
426 case 't': printf(" trace"); break;
427 case 'o': printf(" origin"); break;
428 case 'd': printf(" direction"); break;
429 case 'v': printf(" value"); break;
430 case 'l': printf(" length"); break;
431 case 'L': printf(" first_length"); break;
432 case 'p': printf(" point"); break;
433 case 'n': printf(" normal"); break;
434 case 'N': printf(" unperturbed_normal"); break;
435 case 's': printf(" surface"); break;
436 case 'w': printf(" weight"); break;
437 case 'm': printf(" modifier"); break;
438 }
439 putchar('\n');
440 printf(erract[WARNING].pf != NULL ?
441 "-w+\t\t\t\t# warning messages on\n" :
442 "-w-\t\t\t\t# warning messages off\n");
443 print_rdefaults();
444 }