ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rxtmain.cpp
Revision: 2.2
Committed: Tue Mar 12 16:54:51 2024 UTC (7 weeks, 3 days ago) by greg
Branch: MAIN
Changes since 2.1: +1 -3 lines
Log Message:
perf: added datavector() call for quicker spectral interpolation

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.1 2023/08/21 22:39:05 greg Exp $";
3 #endif
4 /*
5 * rtmain.c - main for rtrace per-ray calculation program
6 */
7
8 #include "copyright.h"
9
10 #include <signal.h>
11
12 #include "rtprocess.h" /* getpid() */
13 #include "platform.h"
14 #include "RtraceSimulManager.h"
15
16 extern char *progname; /* global argv[0] */
17
18 static const char *sigerr[NSIG]; /* signal error messages */
19 char *errfile = NULL; /* error output file */
20
21 extern const char *formstr(int f); /* string from format */
22 extern int setrtoutput(const char *outvals); /* set output values */
23
24 int inform = 'a'; /* input format */
25 int outform = 'a'; /* output format */
26
27 int hresolu = 0; /* horizontal (scan) size */
28 int vresolu = 0; /* vertical resolution */
29
30 RtraceSimulManager myRTmanager; // global simulation manager
31
32 static const char *outvals = "v"; /* output specification */
33 static int nproc = 1; /* number of requested threads */
34 static int doheader = 1; /* include information header? */
35
36 #ifndef MAXMODLIST
37 #define MAXMODLIST 1024 /* maximum modifiers we'll track */
38 #endif
39
40 extern void (*addobjnotify[])(OBJECT); /* object notification calls */
41 extern void tranotify(OBJECT obj);
42
43 char *tralist[MAXMODLIST]; /* list of modifers to trace (or no) */
44 int traincl = -1; /* include == 1, exclude == 0 */
45
46 static void onsig(int signo);
47 static void sigdie(int signo, const char *msg);
48 static void printdefaults(void);
49
50 #define RATRACE_FEATURES "IrradianceCalc\nIrradianceCalc\nDistanceLimiting\n" \
51 "HessianAmbientCache\nAmbientAveraging\n" \
52 "AmbientValueSharing\nAdaptiveShadowTesting\n" \
53 "Outputs=o,d,v,V,w,W,l,L,c,p,n,N,s,m,M,r,x,R,X,~\n"
54
55 int
56 main(int argc, char *argv[])
57 {
58 #define check(ol,al) if (argv[i][ol] || \
59 badarg(argc-i-1,argv+i+1,al)) \
60 goto badopt
61 #define check_bool(olen,var) switch (argv[i][olen]) { \
62 case '\0': var = !var; break; \
63 case 'y': case 'Y': case 't': case 'T': \
64 case '+': case '1': var = 1; break; \
65 case 'n': case 'N': case 'f': case 'F': \
66 case '-': case '0': var = 0; break; \
67 default: goto badopt; }
68 char **tralp = NULL;
69 int rval;
70 int i;
71 /* global program name */
72 progname = argv[0] = fixargv0(argv[0]);
73 /* feature check only? */
74 strcat(RFeatureList, RATRACE_FEATURES);
75 if (argc > 1 && !strcmp(argv[1], "-features"))
76 return feature_status(argc-2, argv+2);
77 /* add trace notify function */
78 for (i = 0; addobjnotify[i] != NULL; i++)
79 ;
80 addobjnotify[i] = tranotify;
81 /* option city */
82 for (i = 1; i < argc; i++) {
83 /* expand arguments */
84 while ((rval = expandarg(&argc, &argv, i)) > 0)
85 ;
86 if (rval < 0) {
87 sprintf(errmsg, "cannot expand '%s'", argv[i]);
88 error(SYSTEM, errmsg);
89 }
90 if (argv[i] == NULL || argv[i][0] != '-')
91 break; /* break from options */
92 if (!strcmp(argv[i], "-version")) {
93 puts(VersionID);
94 quit(0);
95 }
96 if (!strcmp(argv[i], "-defaults") ||
97 !strcmp(argv[i], "-help")) {
98 printdefaults();
99 quit(0);
100 }
101 rval = getrenderopt(argc-i, argv+i);
102 if (rval >= 0) {
103 i += rval;
104 continue;
105 }
106 switch (argv[i][1]) {
107 case 'n': /* number of cores */
108 check(2,"i");
109 nproc = atoi(argv[++i]);
110 break;
111 case 'x': /* x resolution */
112 check(2,"i");
113 hresolu = atoi(argv[++i]);
114 break;
115 case 'y': /* y resolution */
116 check(2,"i");
117 vresolu = atoi(argv[++i]);
118 break;
119 case 'w': /* warnings */
120 rval = erract[WARNING].pf != NULL;
121 check_bool(2,rval);
122 if (rval) erract[WARNING].pf = wputs;
123 else erract[WARNING].pf = NULL;
124 break;
125 case 'e': /* error file */
126 check(2,"s");
127 errfile = argv[++i];
128 break;
129 case 'l': /* limit distance */
130 if (argv[i][2] != 'd')
131 goto badopt;
132 rval = myRTmanager.rtFlags & RTlimDist;
133 check_bool(3,rval);
134 if (rval) myRTmanager.rtFlags |= RTlimDist;
135 else myRTmanager.rtFlags &= ~RTlimDist;
136 break;
137 case 'I': /* immed. irradiance */
138 rval = myRTmanager.rtFlags & RTimmIrrad;
139 check_bool(3,rval);
140 if (rval) myRTmanager.rtFlags |= RTimmIrrad;
141 else myRTmanager.rtFlags &= ~RTimmIrrad;
142 break;
143 case 'f': /* format i/o */
144 switch (argv[i][2]) {
145 case 'a': /* ascii */
146 case 'f': /* float */
147 case 'd': /* double */
148 inform = argv[i][2];
149 break;
150 default:
151 goto badopt;
152 }
153 switch (argv[i][3]) {
154 case '\0':
155 outform = inform;
156 break;
157 case 'a': /* ascii */
158 case 'f': /* float */
159 case 'd': /* double */
160 case 'c': /* color */
161 check(4,"");
162 outform = argv[i][3];
163 break;
164 default:
165 goto badopt;
166 }
167 break;
168 case 'o': /* output */
169 outvals = argv[i]+2;
170 break;
171 case 'h': /* header output */
172 check_bool(2,doheader);
173 break;
174 case 't': /* trace */
175 switch (argv[i][2]) {
176 case 'i': /* include */
177 case 'I':
178 check(3,"s");
179 if (traincl != 1) {
180 traincl = 1;
181 tralp = tralist;
182 }
183 if (argv[i][2] == 'I') { /* file */
184 rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
185 getpath(argv[++i],getrlibpath(),R_OK));
186 if (rval < 0) {
187 sprintf(errmsg,
188 "cannot open trace include file \"%s\"",
189 argv[i]);
190 error(SYSTEM, errmsg);
191 }
192 tralp += rval;
193 } else {
194 *tralp++ = argv[++i];
195 *tralp = NULL;
196 }
197 break;
198 case 'e': /* exclude */
199 case 'E':
200 check(3,"s");
201 if (traincl != 0) {
202 traincl = 0;
203 tralp = tralist;
204 }
205 if (argv[i][2] == 'E') { /* file */
206 rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
207 getpath(argv[++i],getrlibpath(),R_OK));
208 if (rval < 0) {
209 sprintf(errmsg,
210 "cannot open trace exclude file \"%s\"",
211 argv[i]);
212 error(SYSTEM, errmsg);
213 }
214 tralp += rval;
215 } else {
216 *tralp++ = argv[++i];
217 *tralp = NULL;
218 }
219 break;
220 default:
221 goto badopt;
222 }
223 break;
224 default:
225 goto badopt;
226 }
227 }
228 /* set up signal handling */
229 sigdie(SIGINT, "Interrupt");
230 #ifdef SIGHUP
231 sigdie(SIGHUP, "Hangup");
232 #endif
233 sigdie(SIGTERM, "Terminate");
234 #ifdef SIGPIPE
235 sigdie(SIGPIPE, "Broken pipe");
236 #endif
237 #ifdef SIGALRM
238 sigdie(SIGALRM, "Alarm clock");
239 #endif
240 #ifdef SIGXCPU
241 sigdie(SIGXCPU, "CPU limit exceeded");
242 sigdie(SIGXFSZ, "File size exceeded");
243 #endif
244 /* open error file */
245 if (errfile != NULL) {
246 if (freopen(errfile, "a", stderr) == NULL)
247 quit(2);
248 fprintf(stderr, "**************\n*** PID %5d: ",
249 getpid());
250 printargs(argc, argv, stderr);
251 putc('\n', stderr);
252 fflush(stderr);
253 }
254 #ifdef NICE
255 nice(NICE); /* lower priority */
256 #endif
257 /* get octree name */
258 if (i == argc)
259 error(USER, "missing octree argument");
260 if (i != argc-1)
261 goto badopt;
262 /* set output options */
263 rval = setrtoutput(outvals);
264 /* load octree */
265 if (!myRTmanager.LoadOctree(argv[i]))
266 quit(1);
267 /* set up output */
268 if (outform != 'a')
269 SET_FILE_BINARY(stdout);
270 if (doheader) { /* print header? */
271 static char fmt[] = OCTFMT;
272 FILE * octfp = fopen(argv[i], "rb");
273 if (checkheader(octfp, fmt, stdout) < 0)
274 error(USER, "bad octree header");
275 fclose(octfp);
276 printargs(i, argv, stdout);
277 printf("SOFTWARE= %s\n", VersionID);
278 fputnow(stdout);
279 if (rval > 0) /* saved from setrtoutput() call */
280 printf("NCOMP=%d\n", rval);
281 if ((outform == 'f') | (outform == 'd'))
282 fputendian(stdout);
283 fputformat(formstr(outform), stdout);
284 putchar('\n');
285 }
286 rtrace(NULL, nproc); /* trace rays */
287 quit(0); /* clean up & exit */
288
289 badopt:
290 sprintf(errmsg, "command line error at '%s'", argv[i]);
291 error(USER, errmsg);
292 return 1; /* pro forma return */
293
294 #undef check
295 #undef check_bool
296 }
297
298 void
299 wputs( /* warning output function */
300 char *s
301 )
302 {
303 int lasterrno = errno;
304 eputs(s);
305 errno = lasterrno;
306 }
307
308 void
309 eputs( /* put string to stderr */
310 char *s
311 )
312 {
313 static int midline = 0;
314
315 if (!*s)
316 return;
317 if (!midline++) {
318 fputs(progname, stderr);
319 fputs(": ", stderr);
320 }
321 fputs(s, stderr);
322 if (s[strlen(s)-1] == '\n') {
323 fflush(stderr);
324 midline = 0;
325 }
326 }
327
328 static void
329 onsig( /* fatal signal */
330 int signo
331 )
332 {
333 static int gotsig = 0;
334
335 if (gotsig++) /* two signals and we're gone! */
336 _exit(signo);
337
338 #ifdef SIGALRM
339 alarm(15); /* allow 15 seconds to clean up */
340 signal(SIGALRM, SIG_DFL); /* make certain we do die */
341 #endif
342 eputs("signal - ");
343 eputs(sigerr[signo]);
344 eputs("\n");
345 quit(3);
346 }
347
348 static void
349 sigdie( /* set fatal signal */
350 int signo,
351 const char *msg
352 )
353 {
354 if (signal(signo, onsig) == SIG_IGN)
355 signal(signo, SIG_IGN);
356 sigerr[signo] = msg;
357 }
358
359 static void
360 printdefaults(void) /* print default values to stdout */
361 {
362 const char *cp;
363
364 if (myRTmanager.rtFlags & RTimmIrrad)
365 printf("-I+\t\t\t\t# immediate irradiance on\n");
366 printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
367 printf("-x %-9d\t\t\t# %s\n", hresolu,
368 vresolu && hresolu ? "x resolution" : "flush interval");
369 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
370 printf(myRTmanager.rtFlags&RTlimDist ? "-ld+\t\t\t\t# limit distance on\n" :
371 "-ld-\t\t\t\t# limit distance off\n");
372 printf("-h%c\t\t\t\t# %s header\n", doheader ? '+' : '-',
373 doheader ? "output" : "no");
374 printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
375 inform, outform, formstr(inform), formstr(outform));
376 printf("-o%-9s\t\t\t# output", outvals);
377 for (cp = outvals; *cp; cp++)
378 switch (*cp) {
379 case 't': case 'T': printf(" trace"); break;
380 case 'o': printf(" origin"); break;
381 case 'd': printf(" direction"); break;
382 case 'r': printf(" reflect_contrib"); break;
383 case 'R': printf(" reflect_length"); break;
384 case 'x': printf(" unreflect_contrib"); break;
385 case 'X': printf(" unreflect_length"); break;
386 case 'v': printf(" value"); break;
387 case 'V': printf(" contribution"); break;
388 case 'l': printf(" length"); break;
389 case 'L': printf(" first_length"); break;
390 case 'p': printf(" point"); break;
391 case 'n': printf(" normal"); break;
392 case 'N': printf(" unperturbed_normal"); break;
393 case 's': printf(" surface"); break;
394 case 'w': printf(" weight"); break;
395 case 'W': printf(" coefficient"); break;
396 case 'm': printf(" modifier"); break;
397 case 'M': printf(" material"); break;
398 case '~': printf(" tilde"); break;
399 }
400 putchar('\n');
401 printf(erract[WARNING].pf != NULL ?
402 "-w+\t\t\t\t# warning messages on\n" :
403 "-w-\t\t\t\t# warning messages off\n");
404 print_rdefaults();
405 }