ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.8
Committed: Tue Mar 30 16:13:01 2004 UTC (20 years ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R6, rad3R6P1
Changes since 2.7: +23 -24 lines
Log Message:
Continued ANSIfication. There are only bits and pieces left now.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rpmain.c,v 2.7 2003/07/21 22:30:19 schorsch Exp $";
3 #endif
4 /*
5 * rpmain.c - main for rpict batch rendering program
6 */
7
8 #include "copyright.h"
9
10 #include <sys/types.h>
11 #include <signal.h>
12
13 #include "platform.h"
14 #include "rtprocess.h" /* getpid() */
15 #include "ray.h"
16 #include "source.h"
17 #include "ambient.h"
18 #include "random.h"
19 #include "paths.h"
20 #include "view.h"
21
22 /* persistent processes define */
23 #ifdef F_SETLKW
24 #define PERSIST 1 /* normal persist */
25 #define PARALLEL 2 /* parallel persist */
26 #define PCHILD 3 /* child of normal persist */
27 #endif
28
29 char *progname; /* argv[0] */
30 char *octname; /* octree name */
31 char *sigerr[NSIG]; /* signal error messages */
32 char *shm_boundary = NULL; /* boundary of shared memory */
33 char *errfile = NULL; /* error output file */
34
35 extern time_t time();
36 extern time_t tstart; /* start time */
37
38 extern int ralrm; /* seconds between reports */
39
40 extern VIEW ourview; /* viewing parameters */
41
42 extern int hresolu; /* horizontal resolution */
43 extern int vresolu; /* vertical resolution */
44 extern double pixaspect; /* pixel aspect ratio */
45
46 extern int psample; /* pixel sample size */
47 extern double maxdiff; /* max. sample difference */
48 extern double dstrpix; /* square pixel distribution */
49
50 extern double mblur; /* motion blur parameter */
51
52 static void onsig(int signo);
53 static void sigdie(int signo, char *msg);
54 static void printdefaults(void);
55
56
57 int
58 main(int argc, char *argv[])
59 {
60 #define check(ol,al) if (argv[i][ol] || \
61 badarg(argc-i-1,argv+i+1,al)) \
62 goto badopt
63 #define bool(olen,var) switch (argv[i][olen]) { \
64 case '\0': var = !var; break; \
65 case 'y': case 'Y': case 't': case 'T': \
66 case '+': case '1': var = 1; break; \
67 case 'n': case 'N': case 'f': case 'F': \
68 case '-': case '0': var = 0; break; \
69 default: goto badopt; }
70 char *err;
71 char *recover = NULL;
72 char *outfile = NULL;
73 char *zfile = NULL;
74 int loadflags = ~IO_FILES;
75 int seqstart = 0;
76 int persist = 0;
77 int duped1;
78 int rval;
79 int i;
80 /* record start time */
81 tstart = time((time_t *)NULL);
82 /* global program name */
83 progname = argv[0] = fixargv0(argv[0]);
84 /* option city */
85 for (i = 1; i < argc; i++) {
86 /* expand arguments */
87 while ((rval = expandarg(&argc, &argv, i)) > 0)
88 ;
89 if (rval < 0) {
90 sprintf(errmsg, "cannot expand '%s'", argv[i]);
91 error(SYSTEM, errmsg);
92 }
93 if (argv[i] == NULL || argv[i][0] != '-')
94 break; /* break from options */
95 if (!strcmp(argv[i], "-version")) {
96 puts(VersionID);
97 quit(0);
98 }
99 if (!strcmp(argv[i], "-defaults") ||
100 !strcmp(argv[i], "-help")) {
101 printdefaults();
102 quit(0);
103 }
104 rval = getrenderopt(argc-i, argv+i);
105 if (rval >= 0) {
106 i += rval;
107 continue;
108 }
109 rval = getviewopt(&ourview, argc-i, argv+i);
110 if (rval >= 0) {
111 i += rval;
112 continue;
113 }
114 /* rpict options */
115 switch (argv[i][1]) {
116 case 'v': /* view file */
117 if (argv[i][2] != 'f')
118 goto badopt;
119 check(3,"s");
120 rval = viewfile(argv[++i], &ourview, NULL);
121 if (rval < 0) {
122 sprintf(errmsg,
123 "cannot open view file \"%s\"",
124 argv[i]);
125 error(SYSTEM, errmsg);
126 } else if (rval == 0) {
127 sprintf(errmsg,
128 "bad view file \"%s\"",
129 argv[i]);
130 error(USER, errmsg);
131 }
132 break;
133 case 'p': /* pixel */
134 switch (argv[i][2]) {
135 case 's': /* sample */
136 check(3,"i");
137 psample = atoi(argv[++i]);
138 break;
139 case 't': /* threshold */
140 check(3,"f");
141 maxdiff = atof(argv[++i]);
142 break;
143 case 'j': /* jitter */
144 check(3,"f");
145 dstrpix = atof(argv[++i]);
146 break;
147 case 'a': /* aspect */
148 check(3,"f");
149 pixaspect = atof(argv[++i]);
150 break;
151 case 'm': /* motion */
152 check(3,"f");
153 mblur = atof(argv[++i]);
154 break;
155 default:
156 goto badopt;
157 }
158 break;
159 case 'x': /* x resolution */
160 check(2,"i");
161 hresolu = atoi(argv[++i]);
162 break;
163 case 'y': /* y resolution */
164 check(2,"i");
165 vresolu = atoi(argv[++i]);
166 break;
167 case 'S': /* slave index */
168 check(2,"i");
169 seqstart = atoi(argv[++i]);
170 break;
171 case 'o': /* output file */
172 check(2,"s");
173 outfile = argv[++i];
174 break;
175 case 'z': /* z file */
176 check(2,"s");
177 zfile = argv[++i];
178 break;
179 case 'r': /* recover file */
180 if (argv[i][2] == 'o') { /* +output */
181 check(3,"s");
182 outfile = argv[i+1];
183 } else
184 check(2,"s");
185 recover = argv[++i];
186 break;
187 case 't': /* timer */
188 check(2,"i");
189 ralrm = atoi(argv[++i]);
190 break;
191 #ifdef PERSIST
192 case 'P': /* persist file */
193 if (argv[i][2] == 'P') {
194 check(3,"s");
195 persist = PARALLEL;
196 } else {
197 check(2,"s");
198 persist = PERSIST;
199 }
200 persistfile(argv[++i]);
201 break;
202 #endif
203 case 'w': /* warnings */
204 rval = erract[WARNING].pf != NULL;
205 bool(2,rval);
206 if (rval) erract[WARNING].pf = wputs;
207 else erract[WARNING].pf = NULL;
208 break;
209 case 'e': /* error file */
210 check(2,"s");
211 errfile = argv[++i];
212 break;
213 default:
214 goto badopt;
215 }
216 }
217 err = setview(&ourview); /* set viewing parameters */
218 if (err != NULL)
219 error(USER, err);
220 /* initialize object types */
221 initotypes();
222 /* initialize urand */
223 initurand(2048);
224 /* set up signal handling */
225 sigdie(SIGINT, "Interrupt");
226 #ifdef SIGHUP
227 sigdie(SIGHUP, "Hangup");
228 #endif
229 sigdie(SIGTERM, "Terminate");
230 #ifdef SIGPIPE
231 sigdie(SIGPIPE, "Broken pipe");
232 #endif
233 #ifdef SIGALRM
234 sigdie(SIGALRM, "Alarm clock");
235 #endif
236 #ifdef SIGXCPU
237 sigdie(SIGXCPU, "CPU limit exceeded");
238 sigdie(SIGXFSZ, "File size exceeded");
239 #endif
240 /* open error file */
241 if (errfile != NULL) {
242 if (freopen(errfile, "a", stderr) == NULL)
243 quit(2);
244 fprintf(stderr, "**************\n*** PID %5d: ",
245 getpid());
246 printargs(argc, argv, stderr);
247 putc('\n', stderr);
248 fflush(stderr);
249 }
250 #ifdef NICE
251 nice(NICE); /* lower priority */
252 #endif
253 /* get octree */
254 if (i == argc)
255 octname = NULL;
256 else if (i == argc-1)
257 octname = argv[i];
258 else
259 goto badopt;
260 if (seqstart > 0 && octname == NULL)
261 error(USER, "missing octree argument");
262 /* set up output */
263 #ifdef PERSIST
264 if (persist) {
265 if (recover != NULL)
266 error(USER, "persist option used with recover file");
267 if (seqstart <= 0)
268 error(USER, "persist option only for sequences");
269 if (outfile == NULL)
270 duped1 = dup(fileno(stdout)); /* don't lose our output */
271 openheader();
272 } else
273 #endif
274 if (outfile != NULL)
275 openheader();
276 #ifdef _WIN32
277 SET_FILE_BINARY(stdout);
278 if (octname == NULL)
279 SET_FILE_BINARY(stdin);
280 #endif
281 readoct(octname, loadflags, &thescene, NULL);
282 nsceneobjs = nobjects;
283
284 if (loadflags & IO_INFO) { /* print header */
285 printargs(i, argv, stdout);
286 printf("SOFTWARE= %s\n", VersionID);
287 }
288
289 marksources(); /* find and mark sources */
290
291 setambient(); /* initialize ambient calculation */
292
293 #ifdef PERSIST
294 if (persist) {
295 fflush(stdout);
296 if (outfile == NULL) { /* reconnect stdout */
297 dup2(duped1, fileno(stdout));
298 close(duped1);
299 }
300 if (persist == PARALLEL) { /* multiprocessing */
301 preload_objs(); /* preload scene */
302 shm_boundary = (char *)malloc(16);
303 strcpy(shm_boundary, "SHM_BOUNDARY");
304 while ((rval=fork()) == 0) { /* keep on forkin' */
305 pflock(1);
306 pfhold();
307 tstart = time((time_t *)NULL);
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 if (outfile == NULL) /* if out to stdout */
317 dupheader(); /* send header */
318 else /* if out to file */
319 duped1 = dup(fileno(stdout)); /* hang onto pipe */
320 }
321 #endif
322 /* batch render picture(s) */
323 rpict(seqstart, outfile, zfile, recover);
324 /* flush ambient file */
325 ambsync();
326 #ifdef PERSIST
327 if (persist == PERSIST) { /* first run-through */
328 if ((rval=fork()) == 0) { /* child loops until killed */
329 pflock(1);
330 persist = PCHILD;
331 } else { /* original process exits */
332 if (rval < 0)
333 error(SYSTEM, "cannot fork child for persist function");
334 pfdetach(); /* parent exits */
335 }
336 }
337 if (persist == PCHILD) { /* wait for a signal then go again */
338 if (outfile != NULL)
339 close(duped1); /* release output handle */
340 pfhold();
341 tstart = time((time_t *)NULL); /* reinitialize */
342 raynum = nrays = 0;
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 return 1; /* pro forma return */
352
353 #undef check
354 #undef bool
355 }
356
357
358 void
359 wputs( /* warning output function */
360 char *s
361 )
362 {
363 int lasterrno = errno;
364 eputs(s);
365 errno = lasterrno;
366 }
367
368
369 void
370 eputs( /* put string to stderr */
371 register char *s
372 )
373 {
374 static int midline = 0;
375
376 if (!*s)
377 return;
378 if (!midline++) {
379 fputs(progname, stderr);
380 fputs(": ", stderr);
381 }
382 fputs(s, stderr);
383 if (s[strlen(s)-1] == '\n') {
384 fflush(stderr);
385 midline = 0;
386 }
387 }
388
389
390 static void
391 onsig( /* fatal signal */
392 int signo
393 )
394 {
395 static int gotsig = 0;
396
397 if (gotsig++) /* two signals and we're gone! */
398 _exit(signo);
399
400 #ifdef SIGALRM /* XXX how critical is this? */
401 alarm(15); /* allow 15 seconds to clean up */
402 signal(SIGALRM, SIG_DFL); /* make certain we do die */
403 #endif
404 eputs("signal - ");
405 eputs(sigerr[signo]);
406 eputs("\n");
407 quit(3);
408 }
409
410
411 static void
412 sigdie( /* set fatal signal */
413 int signo,
414 char *msg
415 )
416 {
417 if (signal(signo, onsig) == SIG_IGN)
418 signal(signo, SIG_IGN);
419 sigerr[signo] = msg;
420 }
421
422
423 static void
424 printdefaults(void) /* print default values to stdout */
425 {
426 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
427 ourview.type==VT_PER ? "perspective" :
428 ourview.type==VT_PAR ? "parallel" :
429 ourview.type==VT_HEM ? "hemispherical" :
430 ourview.type==VT_ANG ? "angular" :
431 ourview.type==VT_CYL ? "cylindrical" :
432 "unknown");
433 printf("-vp %f %f %f\t# view point\n",
434 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
435 printf("-vd %f %f %f\t# view direction\n",
436 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
437 printf("-vu %f %f %f\t# view up\n",
438 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
439 printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
440 printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
441 printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
442 printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
443 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
444 printf("-vl %f\t\t\t# view lift\n", ourview.voff);
445 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
446 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
447 printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
448 printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
449 printf("-pm %f\t\t\t# pixel motion\n", mblur);
450 printf("-ps %-9d\t\t\t# pixel sample\n", psample);
451 printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
452 printf("-t %-9d\t\t\t# time between reports\n", ralrm);
453 printf(erract[WARNING].pf != NULL ?
454 "-w+\t\t\t\t# warning messages on\n" :
455 "-w-\t\t\t\t# warning messages off\n");
456 print_rdefaults();
457 }