ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rxtmain.cpp
Revision: 2.12
Committed: Wed Mar 5 18:56:28 2025 UTC (8 weeks, 1 day ago) by greg
Branch: MAIN
Changes since 2.11: +9 -3 lines
Log Message:
feat(rtrace,rxtrace): Improved header output

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.12 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.11 2024/11/19 16:27:21 greg Exp $";
3 greg 2.1 #endif
4     /*
5 greg 2.7 * rxtmain.cpp - main for per-ray calculation program
6 greg 2.1 */
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 greg 2.7 double (*sens_curve)(const SCOLOR scol) = NULL; /* spectral conversion for 1-channel */
47 greg 2.3 double out_scalefactor = 1; /* output calibration scale factor */
48     RGBPRIMP out_prims = stdprims; /* output color primitives (NULL if spectral) */
49     static RGBPRIMS our_prims; /* private output color primitives */
50    
51 greg 2.1 static void onsig(int signo);
52     static void sigdie(int signo, const char *msg);
53     static void printdefaults(void);
54    
55 greg 2.10 #define RXTRACE_FEATURES "IrradianceCalc\nMultiprocessing\nDistanceLimiting\n" \
56 greg 2.3 "HessianAmbientCache\nAmbientAveraging\n" \
57     "AmbientValueSharing\nAdaptiveShadowTesting\n" \
58     "Outputs=o,d,v,V,w,W,l,L,c,p,n,N,s,m,M,r,x,R,X,~\n" \
59     "OutputCS=RGB,XYZ,Y,S,M,prims,spec\n"
60 greg 2.1
61     int
62     main(int argc, char *argv[])
63     {
64     #define check(ol,al) if (argv[i][ol] || \
65     badarg(argc-i-1,argv+i+1,al)) \
66     goto badopt
67     #define check_bool(olen,var) switch (argv[i][olen]) { \
68     case '\0': var = !var; break; \
69     case 'y': case 'Y': case 't': case 'T': \
70     case '+': case '1': var = 1; break; \
71     case 'n': case 'N': case 'f': case 'F': \
72     case '-': case '0': var = 0; break; \
73     default: goto badopt; }
74     char **tralp = NULL;
75     int rval;
76     int i;
77     /* global program name */
78 greg 2.3 progname = argv[0];
79 greg 2.1 /* feature check only? */
80 greg 2.3 strcat(RFeatureList, RXTRACE_FEATURES);
81 greg 2.1 if (argc > 1 && !strcmp(argv[1], "-features"))
82     return feature_status(argc-2, argv+2);
83     /* add trace notify function */
84     for (i = 0; addobjnotify[i] != NULL; i++)
85     ;
86     addobjnotify[i] = tranotify;
87     /* option city */
88     for (i = 1; i < argc; i++) {
89     /* expand arguments */
90     while ((rval = expandarg(&argc, &argv, i)) > 0)
91     ;
92     if (rval < 0) {
93     sprintf(errmsg, "cannot expand '%s'", argv[i]);
94     error(SYSTEM, errmsg);
95     }
96     if (argv[i] == NULL || argv[i][0] != '-')
97     break; /* break from options */
98     if (!strcmp(argv[i], "-version")) {
99     puts(VersionID);
100     quit(0);
101     }
102     if (!strcmp(argv[i], "-defaults") ||
103     !strcmp(argv[i], "-help")) {
104     printdefaults();
105     quit(0);
106     }
107     rval = getrenderopt(argc-i, argv+i);
108     if (rval >= 0) {
109     i += rval;
110     continue;
111     }
112     switch (argv[i][1]) {
113     case 'n': /* number of cores */
114     check(2,"i");
115     nproc = atoi(argv[++i]);
116     break;
117     case 'x': /* x resolution */
118     check(2,"i");
119     hresolu = atoi(argv[++i]);
120     break;
121     case 'y': /* y resolution */
122     check(2,"i");
123     vresolu = atoi(argv[++i]);
124     break;
125     case 'w': /* warnings */
126     rval = erract[WARNING].pf != NULL;
127     check_bool(2,rval);
128     if (rval) erract[WARNING].pf = wputs;
129     else erract[WARNING].pf = NULL;
130     break;
131     case 'e': /* error file */
132     check(2,"s");
133     errfile = argv[++i];
134     break;
135     case 'l': /* limit distance */
136     if (argv[i][2] != 'd')
137     goto badopt;
138     rval = myRTmanager.rtFlags & RTlimDist;
139     check_bool(3,rval);
140     if (rval) myRTmanager.rtFlags |= RTlimDist;
141     else myRTmanager.rtFlags &= ~RTlimDist;
142     break;
143     case 'I': /* immed. irradiance */
144     rval = myRTmanager.rtFlags & RTimmIrrad;
145 greg 2.11 check_bool(2,rval);
146 greg 2.1 if (rval) myRTmanager.rtFlags |= RTimmIrrad;
147     else myRTmanager.rtFlags &= ~RTimmIrrad;
148     break;
149     case 'f': /* format i/o */
150     switch (argv[i][2]) {
151     case 'a': /* ascii */
152     case 'f': /* float */
153     case 'd': /* double */
154     inform = argv[i][2];
155     break;
156     default:
157     goto badopt;
158     }
159     switch (argv[i][3]) {
160     case '\0':
161     outform = inform;
162     break;
163     case 'a': /* ascii */
164     case 'f': /* float */
165     case 'd': /* double */
166     case 'c': /* color */
167     check(4,"");
168     outform = argv[i][3];
169     break;
170     default:
171     goto badopt;
172     }
173     break;
174     case 'o': /* output */
175     outvals = argv[i]+2;
176     break;
177     case 'h': /* header output */
178     check_bool(2,doheader);
179     break;
180     case 't': /* trace */
181     switch (argv[i][2]) {
182     case 'i': /* include */
183     case 'I':
184     check(3,"s");
185     if (traincl != 1) {
186     traincl = 1;
187     tralp = tralist;
188     }
189     if (argv[i][2] == 'I') { /* file */
190     rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
191     getpath(argv[++i],getrlibpath(),R_OK));
192     if (rval < 0) {
193     sprintf(errmsg,
194     "cannot open trace include file \"%s\"",
195     argv[i]);
196     error(SYSTEM, errmsg);
197     }
198     tralp += rval;
199     } else {
200     *tralp++ = argv[++i];
201     *tralp = NULL;
202     }
203     break;
204     case 'e': /* exclude */
205     case 'E':
206     check(3,"s");
207     if (traincl != 0) {
208     traincl = 0;
209     tralp = tralist;
210     }
211     if (argv[i][2] == 'E') { /* file */
212     rval = wordfile(tralp, MAXMODLIST-(tralp-tralist),
213     getpath(argv[++i],getrlibpath(),R_OK));
214     if (rval < 0) {
215     sprintf(errmsg,
216     "cannot open trace exclude file \"%s\"",
217     argv[i]);
218     error(SYSTEM, errmsg);
219     }
220     tralp += rval;
221     } else {
222     *tralp++ = argv[++i];
223     *tralp = NULL;
224     }
225     break;
226     default:
227     goto badopt;
228     }
229     break;
230 greg 2.3 case 'p': /* value output */
231     switch (argv[i][2]) {
232     case 'R': /* standard RGB output */
233     if (strcmp(argv[i]+2, "RGB"))
234     goto badopt;
235     out_prims = stdprims;
236     out_scalefactor = 1;
237     sens_curve = NULL;
238     break;
239     case 'X': /* XYZ output */
240     if (strcmp(argv[i]+2, "XYZ"))
241     goto badopt;
242     out_prims = xyzprims;
243     out_scalefactor = WHTEFFICACY;
244     sens_curve = NULL;
245     break;
246     case 'c': {
247     int j;
248     check(3,"ffffffff");
249     rval = 0;
250     for (j = 0; j < 8; j++) {
251     our_prims[0][j] = atof(argv[++i]);
252     rval |= fabs(our_prims[0][j]-stdprims[0][j]) > .001;
253     }
254     if (rval) {
255     if (!colorprimsOK(our_prims))
256     error(USER, "illegal primary chromaticities");
257     out_prims = our_prims;
258     } else
259     out_prims = stdprims;
260     out_scalefactor = 1;
261     sens_curve = NULL;
262     } break;
263     case 'Y': /* photopic response */
264     if (argv[i][3])
265     goto badopt;
266     sens_curve = scolor_photopic;
267     out_scalefactor = WHTEFFICACY;
268     break;
269     case 'S': /* scotopic response */
270     if (argv[i][3])
271     goto badopt;
272     sens_curve = scolor_scotopic;
273     out_scalefactor = WHTSCOTOPIC;
274     break;
275     case 'M': /* melanopic response */
276     if (argv[i][3])
277     goto badopt;
278     sens_curve = scolor_melanopic;
279     out_scalefactor = WHTMELANOPIC;
280     break;
281     default:
282     goto badopt;
283     }
284     break;
285     #if MAXCSAMP>3
286     case 'c': /* output spectral results */
287     if (argv[i][2] != 'o')
288     goto badopt;
289     rval = (out_prims == NULL) & (sens_curve == NULL);
290     check_bool(3,rval);
291     if (rval) {
292     out_prims = NULL;
293     sens_curve = NULL;
294     } else if (out_prims == NULL)
295     out_prims = stdprims;
296     break;
297     #endif
298 greg 2.1 default:
299     goto badopt;
300     }
301     }
302 greg 2.4 /* set/check spectral sampling */
303     rval = setspectrsamp(CNDX, WLPART);
304     if (rval < 0)
305     error(USER, "unsupported spectral sampling");
306 greg 2.12 if (sens_curve != NULL)
307     out_prims = NULL;
308     else if (out_prims != NULL) {
309 greg 2.4 if (!rval)
310     error(WARNING, "spectral range incompatible with color output");
311     } else if (NCSAMP == 3)
312     out_prims = stdprims; /* 3 samples do not a spectrum make */
313 greg 2.1 /* set up signal handling */
314     sigdie(SIGINT, "Interrupt");
315     #ifdef SIGHUP
316     sigdie(SIGHUP, "Hangup");
317     #endif
318     sigdie(SIGTERM, "Terminate");
319     #ifdef SIGPIPE
320     sigdie(SIGPIPE, "Broken pipe");
321     #endif
322     #ifdef SIGALRM
323     sigdie(SIGALRM, "Alarm clock");
324     #endif
325     #ifdef SIGXCPU
326     sigdie(SIGXCPU, "CPU limit exceeded");
327     sigdie(SIGXFSZ, "File size exceeded");
328     #endif
329     /* open error file */
330     if (errfile != NULL) {
331     if (freopen(errfile, "a", stderr) == NULL)
332     quit(2);
333     fprintf(stderr, "**************\n*** PID %5d: ",
334     getpid());
335     printargs(argc, argv, stderr);
336     putc('\n', stderr);
337     fflush(stderr);
338     }
339     #ifdef NICE
340     nice(NICE); /* lower priority */
341     #endif
342     /* get octree name */
343     if (i == argc)
344     error(USER, "missing octree argument");
345     if (i != argc-1)
346     goto badopt;
347     /* set output options */
348     rval = setrtoutput(outvals);
349     /* load octree */
350     if (!myRTmanager.LoadOctree(argv[i]))
351     quit(1);
352     /* set up output */
353     if (outform != 'a')
354     SET_FILE_BINARY(stdout);
355     if (doheader) { /* print header? */
356 greg 2.5 newheader("RADIANCE", stdout);
357 greg 2.9 fputs(myRTmanager.GetHeadStr(), stdout);
358 greg 2.1 printargs(i, argv, stdout);
359     printf("SOFTWARE= %s\n", VersionID);
360     fputnow(stdout);
361     if (rval > 0) /* saved from setrtoutput() call */
362 greg 2.12 fputncomp(rval, stdout);
363     if (NCSAMP > 3)
364     fputwlsplit(WLPART, stdout);
365     if ((out_prims != stdprims) & (out_prims != NULL))
366     fputprims(out_prims, stdout);
367 greg 2.1 if ((outform == 'f') | (outform == 'd'))
368     fputendian(stdout);
369     fputformat(formstr(outform), stdout);
370 greg 2.4 fputc('\n', stdout); /* end of header */
371 greg 2.1 }
372     rtrace(NULL, nproc); /* trace rays */
373     quit(0); /* clean up & exit */
374    
375     badopt:
376     sprintf(errmsg, "command line error at '%s'", argv[i]);
377     error(USER, errmsg);
378     return 1; /* pro forma return */
379    
380     #undef check
381     #undef check_bool
382     }
383    
384     void
385     wputs( /* warning output function */
386     char *s
387     )
388     {
389     int lasterrno = errno;
390     eputs(s);
391     errno = lasterrno;
392     }
393    
394     void
395     eputs( /* put string to stderr */
396 greg 2.8 const char *s
397 greg 2.1 )
398     {
399     static int midline = 0;
400    
401     if (!*s)
402     return;
403     if (!midline++) {
404     fputs(progname, stderr);
405     fputs(": ", stderr);
406     }
407     fputs(s, stderr);
408     if (s[strlen(s)-1] == '\n') {
409     fflush(stderr);
410     midline = 0;
411     }
412     }
413    
414     static void
415     onsig( /* fatal signal */
416     int signo
417     )
418     {
419     static int gotsig = 0;
420    
421     if (gotsig++) /* two signals and we're gone! */
422     _exit(signo);
423    
424     #ifdef SIGALRM
425     alarm(15); /* allow 15 seconds to clean up */
426     signal(SIGALRM, SIG_DFL); /* make certain we do die */
427     #endif
428     eputs("signal - ");
429     eputs(sigerr[signo]);
430     eputs("\n");
431     quit(3);
432     }
433    
434     static void
435     sigdie( /* set fatal signal */
436     int signo,
437     const char *msg
438     )
439     {
440     if (signal(signo, onsig) == SIG_IGN)
441     signal(signo, SIG_IGN);
442     sigerr[signo] = msg;
443     }
444    
445     static void
446     printdefaults(void) /* print default values to stdout */
447     {
448     const char *cp;
449    
450     if (myRTmanager.rtFlags & RTimmIrrad)
451     printf("-I+\t\t\t\t# immediate irradiance on\n");
452     printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
453     printf("-x %-9d\t\t\t# %s\n", hresolu,
454     vresolu && hresolu ? "x resolution" : "flush interval");
455     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
456     printf(myRTmanager.rtFlags&RTlimDist ? "-ld+\t\t\t\t# limit distance on\n" :
457     "-ld-\t\t\t\t# limit distance off\n");
458     printf("-h%c\t\t\t\t# %s header\n", doheader ? '+' : '-',
459     doheader ? "output" : "no");
460     printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
461     inform, outform, formstr(inform), formstr(outform));
462     printf("-o%-9s\t\t\t# output", outvals);
463     for (cp = outvals; *cp; cp++)
464     switch (*cp) {
465     case 't': case 'T': printf(" trace"); break;
466     case 'o': printf(" origin"); break;
467     case 'd': printf(" direction"); break;
468     case 'r': printf(" reflect_contrib"); break;
469     case 'R': printf(" reflect_length"); break;
470     case 'x': printf(" unreflect_contrib"); break;
471     case 'X': printf(" unreflect_length"); break;
472     case 'v': printf(" value"); break;
473     case 'V': printf(" contribution"); break;
474     case 'l': printf(" length"); break;
475     case 'L': printf(" first_length"); break;
476     case 'p': printf(" point"); break;
477     case 'n': printf(" normal"); break;
478     case 'N': printf(" unperturbed_normal"); break;
479     case 's': printf(" surface"); break;
480     case 'w': printf(" weight"); break;
481     case 'W': printf(" coefficient"); break;
482     case 'm': printf(" modifier"); break;
483     case 'M': printf(" material"); break;
484     case '~': printf(" tilde"); break;
485     }
486     putchar('\n');
487 greg 2.3 if (sens_curve == scolor_photopic)
488     printf("-pY\t\t\t\t# photopic output\n");
489     else if (sens_curve == scolor_scotopic)
490     printf("-pS\t\t\t\t# scotopic output\n");
491     else if (sens_curve == scolor_melanopic)
492     printf("-pM\t\t\t\t# melanopic output\n");
493     else if (out_prims == stdprims)
494     printf("-pRGB\t\t\t\t# standard RGB color output\n");
495     else if (out_prims == xyzprims)
496     printf("-pXYZ\t\t\t\t# CIE XYZ color output\n");
497     else if (out_prims != NULL)
498     printf("-pc %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\t# output color primaries and white point\n",
499     out_prims[RED][0], out_prims[RED][1],
500     out_prims[GRN][0], out_prims[GRN][1],
501     out_prims[BLU][0], out_prims[BLU][1],
502     out_prims[WHT][0], out_prims[WHT][1]);
503     if ((sens_curve == NULL) & (NCSAMP > 3))
504     printf(out_prims != NULL ? "-co-\t\t\t\t# output tristimulus colors\n" :
505     "-co+\t\t\t\t# output spectral values\n");
506 greg 2.1 printf(erract[WARNING].pf != NULL ?
507     "-w+\t\t\t\t# warning messages on\n" :
508     "-w-\t\t\t\t# warning messages off\n");
509     print_rdefaults();
510     }