ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpict.c
Revision: 1.9
Committed: Fri Sep 29 08:16:41 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.8: +38 -32 lines
Log Message:
Corrected resolution of output to correspond to request.

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rpict.c - routines and variables for picture generation.
9 *
10 * 8/14/85
11 */
12
13 #include "ray.h"
14
15 #ifdef BSD
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #endif
19
20 #include "view.h"
21
22 #include "random.h"
23
24 VIEW ourview = STDVIEW(512); /* view parameters */
25
26 int psample = 4; /* pixel sample size */
27 double maxdiff = .05; /* max. difference for interpolation */
28 double dstrpix = 0.67; /* square pixel distribution */
29
30 double dstrsrc = 0.0; /* square source distribution */
31 double shadthresh = .05; /* shadow threshold */
32 double shadcert = .5; /* shadow certainty */
33
34 int maxdepth = 6; /* maximum recursion depth */
35 double minweight = 5e-3; /* minimum ray weight */
36
37 COLOR ambval = BLKCOLOR; /* ambient value */
38 double ambacc = 0.2; /* ambient accuracy */
39 int ambres = 32; /* ambient resolution */
40 int ambdiv = 128; /* ambient divisions */
41 int ambssamp = 0; /* ambient super-samples */
42 int ambounce = 0; /* ambient bounces */
43 char *amblist[128]; /* ambient include/exclude list */
44 int ambincl = -1; /* include == 1, exclude == 0 */
45
46 int ralrm = 0; /* seconds between reports */
47
48 double pctdone = 0.0; /* percentage done */
49
50 extern long nrays; /* number of rays traced */
51
52 #define MAXDIV 32 /* maximum sample size */
53
54 #define pixjitter() (.5+dstrpix*(.5-frandom()))
55
56
57 quit(code) /* quit program */
58 int code;
59 {
60 if (code || ralrm > 0) /* report status */
61 report();
62
63 exit(code);
64 }
65
66
67 report() /* report progress */
68 {
69 #ifdef BSD
70 struct rusage rubuf;
71 double t;
72
73 getrusage(RUSAGE_SELF, &rubuf);
74 t = (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
75 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
76 getrusage(RUSAGE_CHILDREN, &rubuf);
77 t += (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
78 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
79
80 sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
81 nrays, pctdone, t/3600.0);
82 #else
83 sprintf(errmsg, "%ld rays, %4.2f%% done\n", nrays, pctdone);
84 #endif
85 eputs(errmsg);
86
87 if (ralrm > 0)
88 alarm(ralrm);
89 }
90
91
92 render(oldfile) /* render the scene */
93 char *oldfile;
94 {
95 COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
96 int ypos; /* current scanline */
97 int xres, yres; /* rendered x and y resolution */
98 COLOR *colptr;
99 register int i;
100 /* set rendered resolution */
101 xres = ourview.hresolu;
102 yres = ourview.vresolu;
103 /* adjust for sampling */
104 if (psample <= 1)
105 psample = 1;
106 else {
107 if (psample > MAXDIV)
108 psample = MAXDIV;
109 /* rendered resolution may be larger */
110 xres += psample-1 - ((ourview.hresolu-2)%psample);
111 yres += psample-1 - ((ourview.vresolu-2)%psample);
112 }
113 /* allocate scanlines */
114 for (i = 0; i <= psample; i++) {
115 scanbar[i] = (COLOR *)malloc(xres*sizeof(COLOR));
116 if (scanbar[i] == NULL)
117 error(SYSTEM, "out of memory in render");
118 }
119 /* write out boundaries */
120 fputresolu(YMAJOR|YDECR, ourview.hresolu, ourview.vresolu, stdout);
121
122 ypos = ourview.vresolu-1 - salvage(oldfile); /* find top line */
123 fillscanline(scanbar[0], xres, ypos, psample); /* top scan */
124
125 for (ypos -= psample; ypos > -psample; ypos -= psample) {
126
127 pctdone = 100.0*(ourview.vresolu-ypos+psample)/ourview.vresolu;
128
129 colptr = scanbar[psample]; /* move base to top */
130 scanbar[psample] = scanbar[0];
131 scanbar[0] = colptr;
132
133 fillscanline(scanbar[0], xres, ypos, psample); /* fill base */
134
135 fillscanbar(scanbar, xres, ypos, psample); /* fill bar */
136
137 for (i = psample; (ypos>0) ? i > 0 : ypos+i >= 0; i--)
138 if (fwritescan(scanbar[i], ourview.hresolu, stdout) < 0)
139 goto writerr;
140 if (fflush(stdout) == EOF)
141 goto writerr;
142 }
143 pctdone = 100.0;
144
145 for (i = 0; i <= psample; i++)
146 free((char *)scanbar[i]);
147 return;
148 writerr:
149 error(SYSTEM, "write error in render");
150 }
151
152
153 fillscanline(scanline, xres, y, xstep) /* fill scan line at y */
154 register COLOR *scanline;
155 int xres, y, xstep;
156 {
157 int b = xstep;
158 register int i;
159
160 pixvalue(scanline[0], 0, y);
161
162 for (i = xstep; i < xres; i += xstep) {
163
164 pixvalue(scanline[i], i, y);
165
166 b = fillsample(scanline+i-xstep, i-xstep, y, xstep, 0, b/2);
167 }
168 }
169
170
171 fillscanbar(scanbar, xres, y, ysize) /* fill interior */
172 register COLOR *scanbar[];
173 int xres, y, ysize;
174 {
175 COLOR vline[MAXDIV+1];
176 int b = ysize;
177 register int i, j;
178
179 for (i = 0; i < xres; i++) {
180
181 copycolor(vline[0], scanbar[0][i]);
182 copycolor(vline[ysize], scanbar[ysize][i]);
183
184 b = fillsample(vline, i, y, 0, ysize, b/2);
185
186 for (j = 1; j < ysize; j++)
187 copycolor(scanbar[j][i], vline[j]);
188 }
189 }
190
191
192 int
193 fillsample(colline, x, y, xlen, ylen, b) /* fill interior points */
194 register COLOR *colline;
195 int x, y;
196 int xlen, ylen;
197 int b;
198 {
199 double ratio;
200 COLOR ctmp;
201 int ncut;
202 register int len;
203
204 if (xlen > 0) /* x or y length is zero */
205 len = xlen;
206 else
207 len = ylen;
208
209 if (len <= 1) /* limit recursion */
210 return(0);
211
212 if (b > 0 || bigdiff(colline[0], colline[len], maxdiff)) {
213
214 pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
215 ncut = 1;
216
217 } else { /* interpolate */
218
219 copycolor(colline[len>>1], colline[len]);
220 ratio = (double)(len>>1) / len;
221 scalecolor(colline[len>>1], ratio);
222 copycolor(ctmp, colline[0]);
223 ratio = 1.0 - ratio;
224 scalecolor(ctmp, ratio);
225 addcolor(colline[len>>1], ctmp);
226 ncut = 0;
227 }
228 /* recurse */
229 ncut += fillsample(colline, x, y, xlen>>1, ylen>>1, (b-1)/2);
230
231 ncut += fillsample(colline + (len>>1), x + (xlen>>1), y + (ylen>>1),
232 xlen - (xlen>>1), ylen - (ylen>>1), b/2);
233
234 return(ncut);
235 }
236
237
238 pixvalue(col, x, y) /* compute pixel value */
239 COLOR col; /* returned color */
240 int x, y; /* pixel position */
241 {
242 static RAY thisray; /* our ray for this pixel */
243
244 rayview(thisray.rorg, thisray.rdir, &ourview,
245 x + pixjitter(), y + pixjitter());
246
247 rayorigin(&thisray, NULL, PRIMARY, 1.0);
248
249 rayvalue(&thisray); /* trace ray */
250
251 copycolor(col, thisray.rcol); /* return color */
252 }
253
254
255 int
256 salvage(oldfile) /* salvage scanlines from killed program */
257 char *oldfile;
258 {
259 COLR *scanline;
260 FILE *fp;
261 int x, y;
262
263 if (oldfile == NULL)
264 return(0);
265
266 if ((fp = fopen(oldfile, "r")) == NULL) {
267 sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
268 error(WARNING, errmsg);
269 return(0);
270 }
271 /* discard header */
272 getheader(fp, NULL);
273 /* get picture size */
274 if (fgetresolu(&x, &y, fp) != (YMAJOR|YDECR)) {
275 sprintf(errmsg, "bad recover file \"%s\"", oldfile);
276 error(WARNING, errmsg);
277 fclose(fp);
278 return(0);
279 }
280
281 if (x != ourview.hresolu || y != ourview.vresolu) {
282 sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
283 oldfile);
284 error(USER, errmsg);
285 }
286
287 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
288 if (scanline == NULL)
289 error(SYSTEM, "out of memory in salvage");
290 for (y = 0; y < ourview.vresolu; y++) {
291 if (freadcolrs(scanline, ourview.hresolu, fp) < 0)
292 break;
293 if (fwritecolrs(scanline, ourview.hresolu, stdout) < 0)
294 goto writerr;
295 }
296 if (fflush(stdout) == EOF)
297 goto writerr;
298 free((char *)scanline);
299 fclose(fp);
300 unlink(oldfile);
301 return(y);
302 writerr:
303 error(SYSTEM, "write error in salvage");
304 }