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 (2 months ago) by greg
Branch: MAIN
Changes since 2.1: +1 -3 lines
Log Message:
perf: added datavector() call for quicker spectral interpolation

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.1 2023/08/21 22:39:05 greg Exp $";
3 greg 2.1 #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     }