ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtmain.c
Revision: 2.5
Committed: Thu Jun 26 00:58:10 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.4: +9 -1 lines
Log Message:
Abstracted process and path handling for Windows.
Renamed FLOAT to RREAL because of conflict on Windows.
Added conditional compiles for some signal handlers.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rtmain.c,v 2.4 2003/06/05 19:29:34 schorsch 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 #ifdef SIGHUP
238 sigdie(SIGHUP, "Hangup");
239 #endif
240 sigdie(SIGTERM, "Terminate");
241 #ifdef SIGPIPE
242 sigdie(SIGPIPE, "Broken pipe");
243 #endif
244 #ifdef SIGALRM
245 sigdie(SIGALRM, "Alarm clock");
246 #endif
247 #ifdef SIGXCPU
248 sigdie(SIGXCPU, "CPU limit exceeded");
249 sigdie(SIGXFSZ, "File size exceeded");
250 #endif
251 /* open error file */
252 if (errfile != NULL) {
253 if (freopen(errfile, "a", stderr) == NULL)
254 quit(2);
255 fprintf(stderr, "**************\n*** PID %5d: ",
256 getpid());
257 printargs(argc, argv, stderr);
258 putc('\n', stderr);
259 fflush(stderr);
260 }
261 #ifdef NICE
262 nice(NICE); /* lower priority */
263 #endif
264 /* get octree */
265 if (i == argc)
266 octname = NULL;
267 else if (i == argc-1)
268 octname = argv[i];
269 else
270 goto badopt;
271 if (octname == NULL)
272 error(USER, "missing octree argument");
273 /* set up output */
274 #ifdef PERSIST
275 if (persist) {
276 duped1 = dup(fileno(stdout)); /* don't lose our output */
277 openheader();
278 }
279 #endif
280 #ifdef _WIN32
281 if (outform != 'a')
282 SET_FILE_BINARY(stdout);
283 if (octname == NULL)
284 SET_FILE_BINARY(stdin);
285 #endif
286 readoct(octname, loadflags, &thescene, NULL);
287 nsceneobjs = nobjects;
288
289 if (loadflags & IO_INFO) { /* print header */
290 printargs(i, argv, stdout);
291 printf("SOFTWARE= %s\n", VersionID);
292 fputnow(stdout);
293 fputformat(formstr(outform), stdout);
294 putchar('\n');
295 }
296
297 marksources(); /* find and mark sources */
298
299 setambient(); /* initialize ambient calculation */
300
301 #ifdef PERSIST
302 if (persist) {
303 fflush(stdout);
304 /* reconnect stdout */
305 dup2(duped1, fileno(stdout));
306 close(duped1);
307 if (persist == PARALLEL) { /* multiprocessing */
308 preload_objs(); /* preload scene */
309 shm_boundary = (char *)malloc(16);
310 strcpy(shm_boundary, "SHM_BOUNDARY");
311 while ((rval=fork()) == 0) { /* keep on forkin' */
312 pflock(1);
313 pfhold();
314 }
315 if (rval < 0)
316 error(SYSTEM, "cannot fork child for persist function");
317 pfdetach(); /* parent exits */
318 }
319 }
320 runagain:
321 if (persist)
322 dupheader(); /* send header to stdout */
323 #endif
324 /* trace rays */
325 rtrace(NULL);
326 /* flush ambient file */
327 ambsync();
328 #ifdef PERSIST
329 if (persist == PERSIST) { /* first run-through */
330 if ((rval=fork()) == 0) { /* child loops until killed */
331 pflock(1);
332 persist = PCHILD;
333 } else { /* original process exits */
334 if (rval < 0)
335 error(SYSTEM, "cannot fork child for persist function");
336 pfdetach(); /* parent exits */
337 }
338 }
339 if (persist == PCHILD) { /* wait for a signal then go again */
340 close(duped1); /* release output handle */
341 pfhold();
342 raynum = nrays = 0; /* reinitialize */
343 goto runagain;
344 }
345 #endif
346 quit(0);
347
348 badopt:
349 sprintf(errmsg, "command line error at '%s'", argv[i]);
350 error(USER, errmsg);
351
352 #undef check
353 #undef bool
354 }
355
356
357 void
358 wputs(s) /* warning output function */
359 char *s;
360 {
361 int lasterrno = errno;
362 eputs(s);
363 errno = lasterrno;
364 }
365
366
367 void
368 eputs(s) /* put string to stderr */
369 register char *s;
370 {
371 static int midline = 0;
372
373 if (!*s)
374 return;
375 if (!midline++) {
376 fputs(progname, stderr);
377 fputs(": ", stderr);
378 }
379 fputs(s, stderr);
380 if (s[strlen(s)-1] == '\n') {
381 fflush(stderr);
382 midline = 0;
383 }
384 }
385
386
387 void
388 onsig(signo) /* fatal signal */
389 int signo;
390 {
391 static int gotsig = 0;
392
393 if (gotsig++) /* two signals and we're gone! */
394 _exit(signo);
395
396 #ifdef SIGALRM
397 alarm(15); /* allow 15 seconds to clean up */
398 signal(SIGALRM, SIG_DFL); /* make certain we do die */
399 #endif
400 eputs("signal - ");
401 eputs(sigerr[signo]);
402 eputs("\n");
403 quit(3);
404 }
405
406
407 void
408 sigdie(signo, msg) /* set fatal signal */
409 int signo;
410 char *msg;
411 {
412 if (signal(signo, onsig) == SIG_IGN)
413 signal(signo, SIG_IGN);
414 sigerr[signo] = msg;
415 }
416
417
418 void
419 printdefaults() /* print default values to stdout */
420 {
421 register char *cp;
422
423 if (imm_irrad)
424 printf("-I+\t\t\t\t# immediate irradiance on\n");
425 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
426 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
427 printf(lim_dist ? "-ld+\t\t\t\t# limit distance on\n" :
428 "-ld-\t\t\t\t# limit distance off\n");
429 printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
430 inform, outform, formstr(inform), formstr(outform));
431 printf("-o%s\t\t\t\t# output", outvals);
432 for (cp = outvals; *cp; cp++)
433 switch (*cp) {
434 case 't': printf(" trace"); break;
435 case 'o': printf(" origin"); break;
436 case 'd': printf(" direction"); break;
437 case 'v': printf(" value"); break;
438 case 'l': printf(" length"); break;
439 case 'L': printf(" first_length"); break;
440 case 'p': printf(" point"); break;
441 case 'n': printf(" normal"); break;
442 case 'N': printf(" unperturbed_normal"); break;
443 case 's': printf(" surface"); break;
444 case 'w': printf(" weight"); break;
445 case 'm': printf(" modifier"); break;
446 }
447 putchar('\n');
448 printf(erract[WARNING].pf != NULL ?
449 "-w+\t\t\t\t# warning messages on\n" :
450 "-w-\t\t\t\t# warning messages off\n");
451 print_rdefaults();
452 }