ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhoptimize.c
Revision: 3.22
Committed: Fri Oct 5 19:19:16 2018 UTC (5 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 3.21: +8 -8 lines
Log Message:
Removed extraneous "extern" and "register" qualifiers

File Contents

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