ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.14
Committed: Mon Jul 21 22:30:18 2003 UTC (20 years, 8 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.13: +4 -4 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

# User Rev Content
1 gwlarson 3.1 #ifndef lint
2 schorsch 3.14 static const char RCSid[] = "$Id: rhoptimize.c,v 3.13 2003/07/14 20:02:29 schorsch Exp $";
3 gwlarson 3.1 #endif
4     /*
5     * Optimize holodeck for quick access.
6     *
7     * 11/4/98 Greg Ward Larson
8     */
9    
10 schorsch 3.12 #include <signal.h>
11     #include <string.h>
12    
13 schorsch 3.13 #include "rtprocess.h" /* getpid() */
14 gwlarson 3.1 #include "holo.h"
15    
16     #ifndef BKBSIZE
17 gwlarson 3.2 #define BKBSIZE 256 /* beam clump size (kilobytes) */
18 gwlarson 3.1 #endif
19    
20     char *progname;
21 gwlarson 3.3 char tempfile[128];
22 gwlarson 3.6 int dupchecking = 0;
23 gwlarson 3.1
24     extern long rhinitcopy();
25    
26    
27     main(argc, argv)
28     int argc;
29     char *argv[];
30     {
31     char *inpname, *outname;
32     int hdfd[2];
33     long nextipos, lastopos, thisopos;
34    
35     progname = argv[0];
36 gwlarson 3.6 argv++; argc--; /* duplicate checking flag? */
37     if (argc > 1 && !strcmp(argv[0], "-u")) {
38     dupchecking++;
39     argv++; argc--;
40     }
41     if (argc < 1 | argc > 2) {
42     fprintf(stderr, "Usage: %s [-u] input.hdk [output.hdk]\n",
43     progname);
44 gwlarson 3.1 exit(1);
45     }
46 gwlarson 3.6 inpname = argv[0]; /* get input file */
47     argv++; argc--;
48     if (argc == 1) /* use given output file */
49     outname = argv[0];
50 gwlarson 3.3 else { /* else use temporary file */
51     if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */
52     sprintf(errmsg, "cannot access \"%s\"", inpname);
53     error(SYSTEM, errmsg);
54     }
55     strcpy(tempfile, inpname);
56 schorsch 3.12 if ((outname = strrchr(tempfile, '/')) != NULL)
57 gwlarson 3.1 outname++;
58     else
59 gwlarson 3.3 outname = tempfile;
60 gwlarson 3.1 sprintf(outname, "rho%d.hdk", getpid());
61 gwlarson 3.3 outname = tempfile;
62 gwlarson 3.1 }
63     /* copy holodeck file header */
64     nextipos = rhinitcopy(hdfd, inpname, outname);
65     lastopos = 0L; /* copy sections one by one */
66     while (nextipos != 0L) {
67     /* set input position; get next */
68 greg 3.8 lseek(hdfd[0], (off_t)nextipos, 0);
69 gwlarson 3.1 read(hdfd[0], (char *)&nextipos, sizeof(nextipos));
70     /* get output position; set last */
71 greg 3.11 thisopos = lseek(hdfd[1], (off_t)0, 2);
72 gwlarson 3.1 if (lastopos > 0L) {
73 greg 3.8 lseek(hdfd[1], (off_t)lastopos, 0);
74 gwlarson 3.1 write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
75 greg 3.11 lseek(hdfd[1], (off_t)0, 2);
76 gwlarson 3.1 }
77     lastopos = thisopos;
78     thisopos = 0L; /* write place holder */
79     write(hdfd[1], (char *)&thisopos, sizeof(thisopos));
80     /* copy holodeck section */
81     copysect(hdfd[0], hdfd[1]);
82     }
83     /* clean up */
84     close(hdfd[0]);
85     close(hdfd[1]);
86 gwlarson 3.3 if (outname == tempfile && rename(outname, inpname) < 0) {
87 gwlarson 3.1 sprintf(errmsg, "cannot rename \"%s\" to \"%s\"",
88     outname, inpname);
89     error(SYSTEM, errmsg);
90     }
91     exit(0);
92     }
93    
94    
95     long
96     rhinitcopy(hfd, infn, outfn) /* open files and copy header */
97     int hfd[2]; /* returned file descriptors */
98     char *infn, *outfn;
99     {
100     FILE *infp, *outfp;
101     long ifpos;
102     /* open files for i/o */
103     if ((infp = fopen(infn, "r")) == NULL) {
104     sprintf(errmsg, "cannot open \"%s\" for reading", infn);
105     error(SYSTEM, errmsg);
106     }
107 greg 3.8 if (access(outfn, F_OK) == 0) {
108     sprintf(errmsg, "output file \"%s\" already exists!", outfn);
109     error(USER, errmsg);
110     }
111 gwlarson 3.1 if ((outfp = fopen(outfn, "w+")) == NULL) {
112     sprintf(errmsg, "cannot open \"%s\" for writing", outfn);
113     error(SYSTEM, errmsg);
114     }
115 gwlarson 3.3 /* set up signal handling */
116     if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN);
117     if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN);
118     if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN);
119     #ifdef SIGXCPU
120     if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN);
121     if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN);
122     #endif
123 gwlarson 3.1 /* copy and verify header */
124 gwlarson 3.3 if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC)
125 gwlarson 3.1 error(USER, "input not in holodeck format");
126     fputformat(HOLOFMT, outfp);
127     fputc('\n', outfp);
128     putw(HOLOMAGIC, outfp);
129     /* get descriptors and free stdio */
130     if ((hfd[0] = dup(fileno(infp))) < 0 ||
131     (hfd[1] = dup(fileno(outfp))) < 0)
132     error(SYSTEM, "dup call failed in rhinitcopy");
133     ifpos = ftell(infp);
134     fclose(infp);
135     if (fclose(outfp) == EOF)
136     error(SYSTEM, "file flushing error in rhinitcopy");
137 gwlarson 3.4 /* check cache size */
138     if (BKBSIZE*1024*1.5 > hdcachesize)
139     hdcachesize = BKBSIZE*1024*1.5;
140 gwlarson 3.1 /* return input position */
141     return(ifpos);
142     }
143    
144    
145 gwlarson 3.6 int
146     nuniq(rva, n) /* sort unique rays to front of beam list */
147     register RAYVAL *rva;
148     int n;
149     {
150     register int i, j;
151     RAYVAL rtmp;
152    
153     for (j = 0; j < n; j++)
154     for (i = j+1; i < n; i++)
155     if ( rva[i].d == rva[j].d &&
156     rva[i].r[0][0]==rva[j].r[0][0] &&
157     rva[i].r[0][1]==rva[j].r[0][1] &&
158     rva[i].r[1][0]==rva[j].r[1][0] &&
159     rva[i].r[1][1]==rva[j].r[1][1] ) {
160     n--; /* swap duplicate with end */
161 schorsch 3.14 rtmp = *(rva+n);
162     *(rva+n) = *(rva+i);
163     *(rva+i) = rtmp;
164 gwlarson 3.6 i--; /* recheck one we swapped */
165     }
166     return(n);
167     }
168    
169    
170 gwlarson 3.5 static BEAMI *beamdir;
171 gwlarson 3.1
172 gwlarson 3.4 static int
173 gwlarson 3.5 bpcmp(b1p, b2p) /* compare beam positions on disk */
174     int *b1p, *b2p;
175 gwlarson 3.1 {
176 greg 3.10 register off_t pdif = beamdir[*b1p].fo - beamdir[*b2p].fo;
177 gwlarson 3.5
178     if (pdif < 0L) return(-1);
179 gwlarson 3.6 return(pdif > 0L);
180 gwlarson 3.2 }
181    
182 gwlarson 3.5 static HOLO *hout;
183    
184     static int
185     xferclump(hp, bq, nb) /* transfer the given clump to hout and free */
186     HOLO *hp;
187     int *bq, nb;
188     {
189     register int i;
190     register BEAM *bp;
191 gwlarson 3.6 int n;
192 gwlarson 3.5
193     beamdir = hp->bi; /* sort based on file position */
194 greg 3.9 qsort((void *)bq, nb, sizeof(*bq), bpcmp);
195 gwlarson 3.5 /* transfer and free each beam */
196     for (i = 0; i < nb; i++) {
197     bp = hdgetbeam(hp, bq[i]);
198 gwlarson 3.6 DCHECK(bp==NULL, CONSISTENCY, "empty beam in xferclump");
199     n = dupchecking ? nuniq(hdbray(bp),bp->nrm) : bp->nrm;
200 schorsch 3.12 memcpy((void *)hdnewrays(hout,bq[i],n),(void *)hdbray(bp),
201 gwlarson 3.6 n*sizeof(RAYVAL));
202 gwlarson 3.5 hdfreebeam(hp, bq[i]);
203     }
204 gwlarson 3.7 hdfreebeam(hout, 0); /* write & free clump */
205 gwlarson 3.5 return(0);
206     }
207    
208 gwlarson 3.1 copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */
209     int ifd, ofd;
210     {
211 gwlarson 3.4 HOLO *hinp;
212 gwlarson 3.1 /* load input section directory */
213     hinp = hdinit(ifd, NULL);
214     /* create output section directory */
215     hout = hdinit(ofd, (HDGRID *)hinp);
216 gwlarson 3.4 /* clump the beams */
217 gwlarson 3.5 clumpbeams(hinp, 0, BKBSIZE*1024, xferclump);
218 gwlarson 3.4 /* clean up */
219 gwlarson 3.1 hddone(hinp);
220     hddone(hout);
221     }
222    
223    
224 greg 3.8 void
225 gwlarson 3.1 eputs(s) /* put error message to stderr */
226     register char *s;
227     {
228     static int midline = 0;
229    
230     if (!*s)
231     return;
232     if (!midline++) { /* prepend line with program name */
233     fputs(progname, stderr);
234     fputs(": ", stderr);
235     }
236     fputs(s, stderr);
237     if (s[strlen(s)-1] == '\n') {
238     fflush(stderr);
239     midline = 0;
240     }
241     }
242    
243    
244 greg 3.8 void
245 gwlarson 3.1 quit(code) /* exit the program gracefully */
246     int code;
247     {
248 gwlarson 3.3 if (tempfile[0])
249     unlink(tempfile);
250 gwlarson 3.1 exit(code);
251     }