ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.17
Committed: Wed Oct 22 02:06:34 2003 UTC (20 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.16: +2 -2 lines
Log Message:
Fewer complaints if "platform.h" precedes "standard.h"

File Contents

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