ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rxtmain.cpp
Revision: 2.6
Committed: Sat Aug 3 21:33:15 2024 UTC (8 months, 4 weeks ago) by greg
Branch: MAIN
Changes since 2.5: +2 -3 lines
Log Message:
feat(rxtrace): changed GetHeader() to return empty string if no header

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id: rxtmain.cpp,v 2.5 2024/08/03 01:54:46 greg Exp $";
3 greg 2.1 #endif
4     /*
5 greg 2.3 * rxtmain.c - 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.3 double (*sens_curve)(SCOLOR scol) = NULL; /* spectral conversion for 1-channel */
47     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.3 #define RXTRACE_FEATURES "IrradianceCalc\nIrradianceCalc\nDistanceLimiting\n" \
56     "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     check_bool(3,rval);
146     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     if (out_prims != NULL) {
307     if (!rval)
308     error(WARNING, "spectral range incompatible with color output");
309     } else if (NCSAMP == 3)
310     out_prims = stdprims; /* 3 samples do not a spectrum make */
311 greg 2.1 /* set up signal handling */
312     sigdie(SIGINT, "Interrupt");
313     #ifdef SIGHUP
314     sigdie(SIGHUP, "Hangup");
315     #endif
316     sigdie(SIGTERM, "Terminate");
317     #ifdef SIGPIPE
318     sigdie(SIGPIPE, "Broken pipe");
319     #endif
320     #ifdef SIGALRM
321     sigdie(SIGALRM, "Alarm clock");
322     #endif
323     #ifdef SIGXCPU
324     sigdie(SIGXCPU, "CPU limit exceeded");
325     sigdie(SIGXFSZ, "File size exceeded");
326     #endif
327     /* open error file */
328     if (errfile != NULL) {
329     if (freopen(errfile, "a", stderr) == NULL)
330     quit(2);
331     fprintf(stderr, "**************\n*** PID %5d: ",
332     getpid());
333     printargs(argc, argv, stderr);
334     putc('\n', stderr);
335     fflush(stderr);
336     }
337     #ifdef NICE
338     nice(NICE); /* lower priority */
339     #endif
340     /* get octree name */
341     if (i == argc)
342     error(USER, "missing octree argument");
343     if (i != argc-1)
344     goto badopt;
345     /* set output options */
346     rval = setrtoutput(outvals);
347     /* load octree */
348     if (!myRTmanager.LoadOctree(argv[i]))
349     quit(1);
350     /* set up output */
351     if (outform != 'a')
352     SET_FILE_BINARY(stdout);
353     if (doheader) { /* print header? */
354 greg 2.5 newheader("RADIANCE", stdout);
355 greg 2.6 fputs(myRTmanager.GetHeader(), stdout);
356 greg 2.1 printargs(i, argv, stdout);
357     printf("SOFTWARE= %s\n", VersionID);
358     fputnow(stdout);
359     if (rval > 0) /* saved from setrtoutput() call */
360     printf("NCOMP=%d\n", rval);
361     if ((outform == 'f') | (outform == 'd'))
362     fputendian(stdout);
363     fputformat(formstr(outform), stdout);
364 greg 2.4 fputc('\n', stdout); /* end of header */
365 greg 2.1 }
366     rtrace(NULL, nproc); /* trace rays */
367     quit(0); /* clean up & exit */
368    
369     badopt:
370     sprintf(errmsg, "command line error at '%s'", argv[i]);
371     error(USER, errmsg);
372     return 1; /* pro forma return */
373    
374     #undef check
375     #undef check_bool
376     }
377    
378     void
379     wputs( /* warning output function */
380     char *s
381     )
382     {
383     int lasterrno = errno;
384     eputs(s);
385     errno = lasterrno;
386     }
387    
388     void
389     eputs( /* put string to stderr */
390     char *s
391     )
392     {
393     static int midline = 0;
394    
395     if (!*s)
396     return;
397     if (!midline++) {
398     fputs(progname, stderr);
399     fputs(": ", stderr);
400     }
401     fputs(s, stderr);
402     if (s[strlen(s)-1] == '\n') {
403     fflush(stderr);
404     midline = 0;
405     }
406     }
407    
408     static void
409     onsig( /* fatal signal */
410     int signo
411     )
412     {
413     static int gotsig = 0;
414    
415     if (gotsig++) /* two signals and we're gone! */
416     _exit(signo);
417    
418     #ifdef SIGALRM
419     alarm(15); /* allow 15 seconds to clean up */
420     signal(SIGALRM, SIG_DFL); /* make certain we do die */
421     #endif
422     eputs("signal - ");
423     eputs(sigerr[signo]);
424     eputs("\n");
425     quit(3);
426     }
427    
428     static void
429     sigdie( /* set fatal signal */
430     int signo,
431     const char *msg
432     )
433     {
434     if (signal(signo, onsig) == SIG_IGN)
435     signal(signo, SIG_IGN);
436     sigerr[signo] = msg;
437     }
438    
439     static void
440     printdefaults(void) /* print default values to stdout */
441     {
442     const char *cp;
443    
444     if (myRTmanager.rtFlags & RTimmIrrad)
445     printf("-I+\t\t\t\t# immediate irradiance on\n");
446     printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
447     printf("-x %-9d\t\t\t# %s\n", hresolu,
448     vresolu && hresolu ? "x resolution" : "flush interval");
449     printf("-y %-9d\t\t\t# y resolution\n", vresolu);
450     printf(myRTmanager.rtFlags&RTlimDist ? "-ld+\t\t\t\t# limit distance on\n" :
451     "-ld-\t\t\t\t# limit distance off\n");
452     printf("-h%c\t\t\t\t# %s header\n", doheader ? '+' : '-',
453     doheader ? "output" : "no");
454     printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
455     inform, outform, formstr(inform), formstr(outform));
456     printf("-o%-9s\t\t\t# output", outvals);
457     for (cp = outvals; *cp; cp++)
458     switch (*cp) {
459     case 't': case 'T': printf(" trace"); break;
460     case 'o': printf(" origin"); break;
461     case 'd': printf(" direction"); break;
462     case 'r': printf(" reflect_contrib"); break;
463     case 'R': printf(" reflect_length"); break;
464     case 'x': printf(" unreflect_contrib"); break;
465     case 'X': printf(" unreflect_length"); break;
466     case 'v': printf(" value"); break;
467     case 'V': printf(" contribution"); break;
468     case 'l': printf(" length"); break;
469     case 'L': printf(" first_length"); break;
470     case 'p': printf(" point"); break;
471     case 'n': printf(" normal"); break;
472     case 'N': printf(" unperturbed_normal"); break;
473     case 's': printf(" surface"); break;
474     case 'w': printf(" weight"); break;
475     case 'W': printf(" coefficient"); break;
476     case 'm': printf(" modifier"); break;
477     case 'M': printf(" material"); break;
478     case '~': printf(" tilde"); break;
479     }
480     putchar('\n');
481 greg 2.3 if (sens_curve == scolor_photopic)
482     printf("-pY\t\t\t\t# photopic output\n");
483     else if (sens_curve == scolor_scotopic)
484     printf("-pS\t\t\t\t# scotopic output\n");
485     else if (sens_curve == scolor_melanopic)
486     printf("-pM\t\t\t\t# melanopic output\n");
487     else if (out_prims == stdprims)
488     printf("-pRGB\t\t\t\t# standard RGB color output\n");
489     else if (out_prims == xyzprims)
490     printf("-pXYZ\t\t\t\t# CIE XYZ color output\n");
491     else if (out_prims != NULL)
492     printf("-pc %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f\t# output color primaries and white point\n",
493     out_prims[RED][0], out_prims[RED][1],
494     out_prims[GRN][0], out_prims[GRN][1],
495     out_prims[BLU][0], out_prims[BLU][1],
496     out_prims[WHT][0], out_prims[WHT][1]);
497     if ((sens_curve == NULL) & (NCSAMP > 3))
498     printf(out_prims != NULL ? "-co-\t\t\t\t# output tristimulus colors\n" :
499     "-co+\t\t\t\t# output spectral values\n");
500 greg 2.1 printf(erract[WARNING].pf != NULL ?
501     "-w+\t\t\t\t# warning messages on\n" :
502     "-w-\t\t\t\t# warning messages off\n");
503     print_rdefaults();
504     }